commit
				
					
						8f3125d2f7
					
				
			
		
					 15 changed files with 424 additions and 95 deletions
				
			
		| 
						 | 
					@ -69,7 +69,9 @@ class UserHostingKeyForm(forms.ModelForm):
 | 
				
			||||||
        # print(self.fields)
 | 
					        # print(self.fields)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def clean_name(self):
 | 
					    def clean_name(self):
 | 
				
			||||||
        return ''.join(random.choice(string.ascii_lowercase) for i in range(7))
 | 
					        return "dcl-priv-key-%s" % (
 | 
				
			||||||
 | 
					            ''.join(random.choice(string.ascii_lowercase) for i in range(7))
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def clean_user(self):
 | 
					    def clean_user(self):
 | 
				
			||||||
        return self.request.user
 | 
					        return self.request.user
 | 
				
			||||||
| 
						 | 
					@ -77,8 +79,6 @@ class UserHostingKeyForm(forms.ModelForm):
 | 
				
			||||||
    def clean(self):
 | 
					    def clean(self):
 | 
				
			||||||
        cleaned_data = self.cleaned_data
 | 
					        cleaned_data = self.cleaned_data
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        print(cleaned_data)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if not cleaned_data.get('public_key'):
 | 
					        if not cleaned_data.get('public_key'):
 | 
				
			||||||
            private_key, public_key = UserHostingKey.generate_keys()
 | 
					            private_key, public_key = UserHostingKey.generate_keys()
 | 
				
			||||||
            cleaned_data.update({
 | 
					            cleaned_data.update({
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										21
									
								
								hosting/migrations/0039_hostingorder_price.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								hosting/migrations/0039_hostingorder_price.py
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,21 @@
 | 
				
			||||||
 | 
					# -*- coding: utf-8 -*-
 | 
				
			||||||
 | 
					# Generated by Django 1.9.4 on 2017-05-12 16:37
 | 
				
			||||||
 | 
					from __future__ import unicode_literals
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from django.db import migrations, models
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Migration(migrations.Migration):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    dependencies = [
 | 
				
			||||||
 | 
					        ('hosting', '0038_auto_20170512_1006'),
 | 
				
			||||||
 | 
					    ]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    operations = [
 | 
				
			||||||
 | 
					        migrations.AddField(
 | 
				
			||||||
 | 
					            model_name='hostingorder',
 | 
				
			||||||
 | 
					            name='price',
 | 
				
			||||||
 | 
					            field=models.FloatField(default=0),
 | 
				
			||||||
 | 
					            preserve_default=False,
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					    ]
 | 
				
			||||||
| 
						 | 
					@ -1,5 +1,7 @@
 | 
				
			||||||
import os
 | 
					import os
 | 
				
			||||||
import socket
 | 
					import socket
 | 
				
			||||||
 | 
					import logging
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import oca
 | 
					import oca
 | 
				
			||||||
from django.db import models
 | 
					from django.db import models
 | 
				
			||||||
| 
						 | 
					@ -19,9 +21,9 @@ from .managers import VMPlansManager
 | 
				
			||||||
from oca.exceptions import OpenNebulaException
 | 
					from oca.exceptions import OpenNebulaException
 | 
				
			||||||
from oca.pool import WrongNameError
 | 
					from oca.pool import WrongNameError
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import logging
 | 
					 | 
				
			||||||
logger = logging.getLogger(__name__)
 | 
					logger = logging.getLogger(__name__)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class HostingOrder(AssignPermissionsMixin, models.Model):
 | 
					class HostingOrder(AssignPermissionsMixin, models.Model):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    ORDER_APPROVED_STATUS = 'Approved'
 | 
					    ORDER_APPROVED_STATUS = 'Approved'
 | 
				
			||||||
| 
						 | 
					@ -35,6 +37,7 @@ class HostingOrder(AssignPermissionsMixin, models.Model):
 | 
				
			||||||
    last4 = models.CharField(max_length=4)
 | 
					    last4 = models.CharField(max_length=4)
 | 
				
			||||||
    cc_brand = models.CharField(max_length=10)
 | 
					    cc_brand = models.CharField(max_length=10)
 | 
				
			||||||
    stripe_charge_id = models.CharField(max_length=100, null=True)
 | 
					    stripe_charge_id = models.CharField(max_length=100, null=True)
 | 
				
			||||||
 | 
					    price = models.FloatField()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    permissions = ('view_hostingorder',)
 | 
					    permissions = ('view_hostingorder',)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -51,9 +54,13 @@ class HostingOrder(AssignPermissionsMixin, models.Model):
 | 
				
			||||||
        return self.ORDER_APPROVED_STATUS if self.approved else self.ORDER_DECLINED_STATUS
 | 
					        return self.ORDER_APPROVED_STATUS if self.approved else self.ORDER_DECLINED_STATUS
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @classmethod
 | 
					    @classmethod
 | 
				
			||||||
    def create(cls, vm_plan=None, customer=None, billing_address=None):
 | 
					    def create(cls, price=None, vm_id=None, customer=None, billing_address=None):
 | 
				
			||||||
        instance = cls.objects.create(vm_plan=vm_plan, customer=customer,
 | 
					        instance = cls.objects.create(
 | 
				
			||||||
                                      billing_address=billing_address)
 | 
					            price=price,
 | 
				
			||||||
 | 
					            vm_id=vm_id,
 | 
				
			||||||
 | 
					            customer=customer,
 | 
				
			||||||
 | 
					            billing_address=billing_address
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
        instance.assign_permissions(customer.user)
 | 
					        instance.assign_permissions(customer.user)
 | 
				
			||||||
        return instance
 | 
					        return instance
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -67,6 +74,12 @@ class HostingOrder(AssignPermissionsMixin, models.Model):
 | 
				
			||||||
        self.cc_brand = stripe_charge.source.brand
 | 
					        self.cc_brand = stripe_charge.source.brand
 | 
				
			||||||
        self.save()
 | 
					        self.save()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def get_cc_data(self):
 | 
				
			||||||
 | 
					        return {
 | 
				
			||||||
 | 
					            'last4': self.last4,
 | 
				
			||||||
 | 
					            'cc_brand': self.cc_brand,
 | 
				
			||||||
 | 
					        } if self.last4 and self.cc_brand else None
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class UserHostingKey(models.Model):
 | 
					class UserHostingKey(models.Model):
 | 
				
			||||||
    user = models.ForeignKey(CustomUser)
 | 
					    user = models.ForeignKey(CustomUser)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -35,7 +35,7 @@ class OpenNebulaManager:
 | 
				
			||||||
        '11': 'CLONING_FAILURE',
 | 
					        '11': 'CLONING_FAILURE',
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def __init__(self, email=None, password=None, create_user=True):
 | 
					    def __init__(self, email=None, password=None):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Get oneadmin client
 | 
					        # Get oneadmin client
 | 
				
			||||||
        self.oneadmin_client = self._get_opennebula_client(
 | 
					        self.oneadmin_client = self._get_opennebula_client(
 | 
				
			||||||
| 
						 | 
					@ -43,9 +43,6 @@ class OpenNebulaManager:
 | 
				
			||||||
            settings.OPENNEBULA_PASSWORD
 | 
					            settings.OPENNEBULA_PASSWORD
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if not create_user:
 | 
					 | 
				
			||||||
            return
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        # Get or create oppenebula user using given credentials
 | 
					        # Get or create oppenebula user using given credentials
 | 
				
			||||||
        self.opennebula_user = self._get_or_create_user(
 | 
					        self.opennebula_user = self._get_or_create_user(
 | 
				
			||||||
            email,
 | 
					            email,
 | 
				
			||||||
| 
						 | 
					@ -121,9 +118,17 @@ class OpenNebulaManager:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return vm_data
 | 
					        return vm_data
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def change_user_password(self, new_password):
 | 
				
			||||||
 | 
					        self.oneadmin_client.call(
 | 
				
			||||||
 | 
					            oca.User.METHODS['passwd'],
 | 
				
			||||||
 | 
					            self.opennebula_user.id,
 | 
				
			||||||
 | 
					            new_password
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def create_vm(self, specs):
 | 
					    def create_vm(self, specs):
 | 
				
			||||||
        vm_id = None
 | 
					        vm_id = None
 | 
				
			||||||
        try:
 | 
					        try:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            # We do have the vm_template param set. Get and parse it
 | 
					            # We do have the vm_template param set. Get and parse it
 | 
				
			||||||
            # and check it to be in the desired range.
 | 
					            # and check it to be in the desired range.
 | 
				
			||||||
            # We have 8 possible VM templates for the moment which are 1x, 2x, 4x ...
 | 
					            # We have 8 possible VM templates for the moment which are 1x, 2x, 4x ...
 | 
				
			||||||
| 
						 | 
					@ -136,6 +141,9 @@ class OpenNebulaManager:
 | 
				
			||||||
                                        <TYPE>{disk_type}</TYPE>
 | 
					                                        <TYPE>{disk_type}</TYPE>
 | 
				
			||||||
                                        <SIZE>{size}</SIZE>
 | 
					                                        <SIZE>{size}</SIZE>
 | 
				
			||||||
                                      </DISK>
 | 
					                                      </DISK>
 | 
				
			||||||
 | 
					                                      <CONTEXT>
 | 
				
			||||||
 | 
					                                        <SSH_PUBLIC_KEY>{ssh_key}</SSH_PUBLIC_KEY>
 | 
				
			||||||
 | 
					                                      </CONTEXT>
 | 
				
			||||||
                                    </VM>
 | 
					                                    </VM>
 | 
				
			||||||
                                    """
 | 
					                                    """
 | 
				
			||||||
            vm_id = oca.VirtualMachine.allocate(
 | 
					            vm_id = oca.VirtualMachine.allocate(
 | 
				
			||||||
| 
						 | 
					@ -145,7 +153,8 @@ class OpenNebulaManager:
 | 
				
			||||||
                    vcpu=specs.get('cores'),
 | 
					                    vcpu=specs.get('cores'),
 | 
				
			||||||
                    cpu=0.1 * specs.get('cores'),
 | 
					                    cpu=0.1 * specs.get('cores'),
 | 
				
			||||||
                    disk_type='fs',
 | 
					                    disk_type='fs',
 | 
				
			||||||
                    size=10000 * specs.get('disk_size')
 | 
					                    size=10000 * specs.get('disk_size'),
 | 
				
			||||||
 | 
					                    ssh_key=specs.get('ssh_key')
 | 
				
			||||||
                )
 | 
					                )
 | 
				
			||||||
            )
 | 
					            )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -155,10 +164,6 @@ class OpenNebulaManager:
 | 
				
			||||||
                self.opennebula_user.id,
 | 
					                self.opennebula_user.id,
 | 
				
			||||||
                self.opennebula_user.group_ids[0]
 | 
					                self.opennebula_user.group_ids[0]
 | 
				
			||||||
            )
 | 
					            )
 | 
				
			||||||
            # oca.VirtualMachine.chown(
 | 
					 | 
				
			||||||
            #     vm_id,
 | 
					 | 
				
			||||||
               
 | 
					 | 
				
			||||||
            # )
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        except socket.timeout as socket_err:
 | 
					        except socket.timeout as socket_err:
 | 
				
			||||||
            logger.error("Socket timeout error: {0}".format(socket_err))
 | 
					            logger.error("Socket timeout error: {0}".format(socket_err))
 | 
				
			||||||
| 
						 | 
					@ -171,6 +176,34 @@ class OpenNebulaManager:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return vm_id
 | 
					        return vm_id
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def terminate_vm(self, vm_id):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        TERMINATE_ACTION = 'terminate'
 | 
				
			||||||
 | 
					        vm_terminated = False
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        try:
 | 
				
			||||||
 | 
					            self.oneadmin_client.call(
 | 
				
			||||||
 | 
					                oca.VirtualMachine.METHODS['action'],
 | 
				
			||||||
 | 
					                TERMINATE_ACTION,
 | 
				
			||||||
 | 
					                int(vm_id),
 | 
				
			||||||
 | 
					            )
 | 
				
			||||||
 | 
					            vm_terminated = True
 | 
				
			||||||
 | 
					        except socket.timeout as socket_err:
 | 
				
			||||||
 | 
					            logger.error("Socket timeout error: {0}".format(socket_err))
 | 
				
			||||||
 | 
					        except OpenNebulaException as opennebula_err:
 | 
				
			||||||
 | 
					            logger.error("OpenNebulaException error: {0}".format(opennebula_err))
 | 
				
			||||||
 | 
					        except OSError as os_err:
 | 
				
			||||||
 | 
					            logger.error("OSError : {0}".format(os_err))
 | 
				
			||||||
 | 
					        except ValueError as value_err:
 | 
				
			||||||
 | 
					            logger.error("ValueError : {0}".format(value_err))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return vm_terminated
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def get_vm_templates(self):
 | 
				
			||||||
 | 
					        template_pool = oca.VmTemplatePool(self.oneadmin_client)
 | 
				
			||||||
 | 
					        template_pool.info()
 | 
				
			||||||
 | 
					        return template_pool
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def get_vm(self, email, vm_id):
 | 
					    def get_vm(self, email, vm_id):
 | 
				
			||||||
        # Get vm's
 | 
					        # Get vm's
 | 
				
			||||||
        vms = self.get_vms(email)
 | 
					        vms = self.get_vms(email)
 | 
				
			||||||
| 
						 | 
					@ -198,9 +231,6 @@ class OpenNebulaManager:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return vm_pool
 | 
					        return vm_pool
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class HostingManageVMAdmin(admin.ModelAdmin):
 | 
					class HostingManageVMAdmin(admin.ModelAdmin):
 | 
				
			||||||
    client = None
 | 
					    client = None
 | 
				
			||||||
    oneadmin_client = None
 | 
					    oneadmin_client = None
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -25,6 +25,27 @@ $( document ).ready(function() {
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    var hasCreditcard = window.hasCreditcard || false;
 | 
				
			||||||
 | 
					    console.log("has creditcard", hasCreditcard);
 | 
				
			||||||
 | 
					    // hasCreditcard= true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    var submit_form_btn = $('#payment_button_with_creditcard');
 | 
				
			||||||
 | 
					    submit_form_btn.on('click', submit_payment);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    function submit_payment(e){ 
 | 
				
			||||||
 | 
					      e.preventDefault();
 | 
				
			||||||
 | 
					      console.log("creditcard sdasd");
 | 
				
			||||||
 | 
					      // if (hasCreditcard) {
 | 
				
			||||||
 | 
					         $('#billing-form').submit();
 | 
				
			||||||
 | 
					         console.log("has creditcard2");
 | 
				
			||||||
 | 
					      // }
 | 
				
			||||||
 | 
					     
 | 
				
			||||||
 | 
					      // $form.submit();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    var $form = $('#payment-form');
 | 
					    var $form = $('#payment-form');
 | 
				
			||||||
    $form.submit(payWithStripe);
 | 
					    $form.submit(payWithStripe);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -17,14 +17,14 @@
 | 
				
			||||||
                               
 | 
					                               
 | 
				
			||||||
                                  <option value="{{template.id}}">
 | 
					                                  <option value="{{template.id}}">
 | 
				
			||||||
                                                CORE: {{template.cores}},
 | 
					                                                CORE: {{template.cores}},
 | 
				
			||||||
                                                RAM: {{template.memory}},r
 | 
					                                                RAM: {{template.memory}} GiB, 
 | 
				
			||||||
                                                SSD: {{template.disk_size}}
 | 
					                                                SSD: {{template.disk_size}} GiB
 | 
				
			||||||
                                  </option>
 | 
					                                  </option>
 | 
				
			||||||
                                
 | 
					                                
 | 
				
			||||||
                            {% endfor %}
 | 
					                            {% endfor %}
 | 
				
			||||||
                        </select>
 | 
					                        </select>
 | 
				
			||||||
                    </div> 
 | 
					                    </div> 
 | 
				
			||||||
                    <div class="form-group">
 | 
					<!--                     <div class="form-group">
 | 
				
			||||||
                        Select VM Configuration:
 | 
					                        Select VM Configuration:
 | 
				
			||||||
                        <select name="configuration">
 | 
					                        <select name="configuration">
 | 
				
			||||||
                            {% for config in configuration_options %}
 | 
					                            {% for config in configuration_options %}
 | 
				
			||||||
| 
						 | 
					@ -33,7 +33,7 @@
 | 
				
			||||||
                                
 | 
					                                
 | 
				
			||||||
                            {% endfor %}
 | 
					                            {% endfor %}
 | 
				
			||||||
                        </select>
 | 
					                        </select>
 | 
				
			||||||
                    </div>                          
 | 
					                    </div>  -->                         
 | 
				
			||||||
                    <div class="form-group">
 | 
					                    <div class="form-group">
 | 
				
			||||||
                        <button class="btn btn-success" >{% trans "Start VM"%} </button>                         
 | 
					                        <button class="btn btn-success" >{% trans "Start VM"%} </button>                         
 | 
				
			||||||
                    </div>
 | 
					                    </div>
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -8,7 +8,7 @@
 | 
				
			||||||
			<div class="col-xs-12 col-md-4 col-md-offset-2 billing">
 | 
								<div class="col-xs-12 col-md-4 col-md-offset-2 billing">
 | 
				
			||||||
				<h3><b>Billing Address</b></h3>
 | 
									<h3><b>Billing Address</b></h3>
 | 
				
			||||||
				<hr>
 | 
									<hr>
 | 
				
			||||||
				<form role="form" id="billing-form" method="post" action="{% url 'hosting:payment' %}" novalidate>
 | 
									<form role="form" id="billing-form" method="post" action="" novalidate>
 | 
				
			||||||
	                {% for field in form %}
 | 
						                {% for field in form %}
 | 
				
			||||||
                        {% csrf_token %}
 | 
					                        {% csrf_token %}
 | 
				
			||||||
	                    {% bootstrap_field field show_label=False type='fields'%}
 | 
						                    {% bootstrap_field field show_label=False type='fields'%}
 | 
				
			||||||
| 
						 | 
					@ -23,6 +23,17 @@
 | 
				
			||||||
				<hr>
 | 
									<hr>
 | 
				
			||||||
	            <div>
 | 
						            <div>
 | 
				
			||||||
	                <div>
 | 
						                <div>
 | 
				
			||||||
 | 
					                    {% if credit_card_data.last4 %}
 | 
				
			||||||
 | 
					                      <form role="form" id="payment-form-with-creditcard"novalidate>
 | 
				
			||||||
 | 
					                        <h5 class="billing-head">Credit Card</h5>
 | 
				
			||||||
 | 
					                        <h5 class="membership-lead">Last 4: *****{{credit_card_data.last4}}</h5>
 | 
				
			||||||
 | 
					                        <h5 class="membership-lead">Type: {{credit_card_data.cc_brand}}</h5>
 | 
				
			||||||
 | 
					                        <input type="hidden" name="credit_card_needed" value="false"/>
 | 
				
			||||||
 | 
					                      </form>  
 | 
				
			||||||
 | 
					                     <button id="payment_button_with_creditcard" class="btn btn-success btn-lg btn-block" type="submit">Submit Payment</button>
 | 
				
			||||||
 | 
					                    {% else %}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	                    <form role="form" id="payment-form" novalidate>
 | 
						                    <form role="form" id="payment-form" novalidate>
 | 
				
			||||||
	                        <div class="row">
 | 
						                        <div class="row">
 | 
				
			||||||
	                            <div class="col-xs-9 col-md-12">
 | 
						                            <div class="col-xs-9 col-md-12">
 | 
				
			||||||
| 
						 | 
					@ -76,6 +87,7 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                           
 | 
					                           
 | 
				
			||||||
	                    </form>
 | 
						                    </form>
 | 
				
			||||||
 | 
					                    {% endif %}
 | 
				
			||||||
	                </div>
 | 
						                </div>
 | 
				
			||||||
	            </div>
 | 
						            </div>
 | 
				
			||||||
	        </div>
 | 
						        </div>
 | 
				
			||||||
| 
						 | 
					@ -109,6 +121,7 @@
 | 
				
			||||||
	</div>
 | 
						</div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
</div>
 | 
					</div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<!-- stripe key data -->
 | 
					<!-- stripe key data -->
 | 
				
			||||||
{% if stripe_key %}
 | 
					{% if stripe_key %}
 | 
				
			||||||
<script type="text/javascript"> 
 | 
					<script type="text/javascript"> 
 | 
				
			||||||
| 
						 | 
					@ -116,6 +129,13 @@
 | 
				
			||||||
</script>
 | 
					</script>
 | 
				
			||||||
{%endif%}
 | 
					{%endif%}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					{% if credit_card_data.last4 and credit_card_data.cc_brand %}
 | 
				
			||||||
 | 
					<script type="text/javascript"> 
 | 
				
			||||||
 | 
					     (function () {window.hasCreditcard = true;})();
 | 
				
			||||||
 | 
					</script>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					{%endif%}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
{%endblock%}
 | 
					{%endblock%}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -79,7 +79,7 @@
 | 
				
			||||||
								      <div class="col-md-3">
 | 
													      <div class="col-md-3">
 | 
				
			||||||
								        <div class="well text-center">
 | 
													        <div class="well text-center">
 | 
				
			||||||
								        	<i class="fa fa-hdd-o" aria-hidden="true"></i> {% trans "Disk"%} <br/>
 | 
													        	<i class="fa fa-hdd-o" aria-hidden="true"></i> {% trans "Disk"%} <br/>
 | 
				
			||||||
								        	<span class="label label-success">{{virtual_machine.disk_size}} GiB</span>
 | 
													        	<span class="label label-success">{{virtual_machine.disk_size|floatformat:2}} GiB</span>
 | 
				
			||||||
								        </div>
 | 
													        </div>
 | 
				
			||||||
								      </div>
 | 
													      </div>
 | 
				
			||||||
								    </div><!--/row-->    
 | 
													    </div><!--/row-->    
 | 
				
			||||||
| 
						 | 
					@ -107,6 +107,7 @@
 | 
				
			||||||
				            	<div class="row ">
 | 
									            	<div class="row ">
 | 
				
			||||||
									<div class="col-md-12 inline-headers">
 | 
														<div class="col-md-12 inline-headers">
 | 
				
			||||||
										<h3>{% trans "Current status"%}</h3>
 | 
															<h3>{% trans "Current status"%}</h3>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
										<div  class="pull-right space-above">
 | 
															<div  class="pull-right space-above">
 | 
				
			||||||
											{% if virtual_machine.state == 'PENDING' %}
 | 
																{% if virtual_machine.state == 'PENDING' %}
 | 
				
			||||||
												<span class="label
 | 
																	<span class="label
 | 
				
			||||||
| 
						 | 
					@ -130,17 +131,28 @@
 | 
				
			||||||
											{% csrf_token %} 
 | 
																{% csrf_token %} 
 | 
				
			||||||
											</form>	
 | 
																</form>	
 | 
				
			||||||
												
 | 
																	
 | 
				
			||||||
												<button type="text"
 | 
																	<button type="text" data-href="{% url 'hosting:virtual_machines' virtual_machine.vm_id %}" data-toggle="modal" data-target="#confirm-cancel" class="btn btn-danger">{% trans "Terminate Virtual Machine"%}</button>
 | 
				
			||||||
                    data-href="{% url 'hosting:virtual_machines' virtual_machine.vm_id %}" data-toggle="modal" data-target="#confirm-cancel" class="btn btn-danger">{% trans "Cancel Virtual Machine"%}</button>
 | 
					 | 
				
			||||||
																						
 | 
																											
 | 
				
			||||||
										</div>
 | 
															</div>
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
									</div>
 | 
														</div>
 | 
				
			||||||
 | 
					                                    <div class="col-md-12">
 | 
				
			||||||
 | 
					                                        <br/>
 | 
				
			||||||
 | 
					                                        {% if messages %}
 | 
				
			||||||
 | 
					                                            <div class="alert alert-warning">
 | 
				
			||||||
 | 
					                                                {% for message in messages %}
 | 
				
			||||||
 | 
					                                                <span>{{ message }}</span>
 | 
				
			||||||
 | 
					                                                {% endfor %}
 | 
				
			||||||
 | 
					                                            </div>
 | 
				
			||||||
 | 
					                                        {% endif %}
 | 
				
			||||||
 | 
					                                    </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
									<!-- Cancel Modal -->
 | 
														<!-- Cancel Modal -->
 | 
				
			||||||
									<div class="modal fade" id="confirm-cancel" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
 | 
														<div class="modal fade" id="confirm-cancel" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
 | 
				
			||||||
									    <div class="modal-dialog">
 | 
														    <div class="modal-dialog">
 | 
				
			||||||
									        <div class="modal-content">
 | 
														        <div class="modal-content">
 | 
				
			||||||
									            <div class="modal-header">
 | 
														            <div class="modal-header">
 | 
				
			||||||
									                {% trans "Cancel your Virtual Machine"%}
 | 
														                {% trans "Terminate your Virtual Machine"%}
 | 
				
			||||||
									            </div>
 | 
														            </div>
 | 
				
			||||||
									            <div class="modal-body">
 | 
														            <div class="modal-body">
 | 
				
			||||||
									                {% trans "Are you sure do you want to cancel your Virtual Machine "%} {{virtual_machine.name}}  {% trans "plan?"%}
 | 
														                {% trans "Are you sure do you want to cancel your Virtual Machine "%} {{virtual_machine.name}}  {% trans "plan?"%}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -9,11 +9,18 @@
 | 
				
			||||||
                    <form method="POST" action="" >
 | 
					                    <form method="POST" action="" >
 | 
				
			||||||
                        {% csrf_token %}
 | 
					                        {% csrf_token %}
 | 
				
			||||||
				        <h3><i class="fa fa-key" aria-hidden="true"></i>{% trans "Access Key"%} </h3>
 | 
									        <h3><i class="fa fa-key" aria-hidden="true"></i>{% trans "Access Key"%} </h3>
 | 
				
			||||||
 | 
					                        {% if messages %}
 | 
				
			||||||
 | 
					                        <div class="alert alert-warning">
 | 
				
			||||||
 | 
					                            {% for message in messages %}
 | 
				
			||||||
 | 
					                            <span>{{ message }}</span>
 | 
				
			||||||
 | 
					                            {% endfor %}
 | 
				
			||||||
 | 
					                        </div>
 | 
				
			||||||
 | 
					                        {% endif %}
 | 
				
			||||||
				        <hr/>	
 | 
									        <hr/>	
 | 
				
			||||||
                        {% if not user_key %}
 | 
					                        {% if not user_key %}
 | 
				
			||||||
                            <div class="alert alert-warning">
 | 
					                            <h3>
 | 
				
			||||||
                                {% trans "Upload your own key. "%} 
 | 
					                                {% trans "Upload your own key. "%} 
 | 
				
			||||||
                            </div>
 | 
					                            </h3>
 | 
				
			||||||
                            <div class="form-group">
 | 
					                            <div class="form-group">
 | 
				
			||||||
                              <label for="comment">Paste here your public key</label>
 | 
					                              <label for="comment">Paste here your public key</label>
 | 
				
			||||||
                              <textarea class="form-control" rows="6" name="public_key"></textarea>
 | 
					                              <textarea class="form-control" rows="6" name="public_key"></textarea>
 | 
				
			||||||
| 
						 | 
					@ -22,10 +29,10 @@
 | 
				
			||||||
                                <button class="btn btn-success">{% trans "Upload Key"%} </a>
 | 
					                                <button class="btn btn-success">{% trans "Upload Key"%} </a>
 | 
				
			||||||
                            </div>
 | 
					                            </div>
 | 
				
			||||||
                        
 | 
					                        
 | 
				
			||||||
                            <div class="alert alert-warning">
 | 
					                            <h3>
 | 
				
			||||||
                                {% trans "Or generate a new key pair."%} 
 | 
					                                {% trans "Or generate a new key pair."%} 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                            </div>
 | 
					                            </h3>
 | 
				
			||||||
                            <div class="form-group">
 | 
					                            <div class="form-group">
 | 
				
			||||||
                                <button class="btn btn-success">{% trans "Generate Key Pair"%} </a>
 | 
					                                <button class="btn btn-success">{% trans "Generate Key Pair"%} </a>
 | 
				
			||||||
                            </div>
 | 
					                            </div>
 | 
				
			||||||
| 
						 | 
					@ -58,7 +65,7 @@
 | 
				
			||||||
				        {% if private_key %}
 | 
									        {% if private_key %}
 | 
				
			||||||
				 		<div class="alert alert-warning">
 | 
									 		<div class="alert alert-warning">
 | 
				
			||||||
				 			 
 | 
									 			 
 | 
				
			||||||
  							<strong>{% trans "Warning!"%}</strong>{% trans "You can view your SSH  private key once. Copy it or if it wasn't downloaded automatically, just click on Download to start it."%}  
 | 
					  							<strong>{% trans "Warning!"%}</strong>{% trans "You can download your SSH  private key once. Don't lost your key"%}  
 | 
				
			||||||
						</div>
 | 
											</div>
 | 
				
			||||||
						<div class="form-group">
 | 
											<div class="form-group">
 | 
				
			||||||
						  <textarea class="form-control" rows="6" id="ssh_key" type="hidden" style="display:none">{{private_key}}</textarea>
 | 
											  <textarea class="form-control" rows="6" id="ssh_key" type="hidden" style="display:none">{{private_key}}</textarea>
 | 
				
			||||||
| 
						 | 
					@ -101,6 +108,7 @@
 | 
				
			||||||
		// Remove anchor from body
 | 
							// Remove anchor from body
 | 
				
			||||||
		document.body.removeChild(a);
 | 
							document.body.removeChild(a);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
</script>
 | 
					</script>
 | 
				
			||||||
{%endif%}
 | 
					{%endif%}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -11,6 +11,16 @@
 | 
				
			||||||
                    <a class="btn btn-success" href="{% url 'hosting:create-virtual-machine' %}" >{% trans "Create VM"%} </a>                    
 | 
					                    <a class="btn btn-success" href="{% url 'hosting:create-virtual-machine' %}" >{% trans "Create VM"%} </a>                    
 | 
				
			||||||
                </p>
 | 
					                </p>
 | 
				
			||||||
				<br/>
 | 
									<br/>
 | 
				
			||||||
 | 
					                <div class="col-md-12">
 | 
				
			||||||
 | 
					                    <br/>
 | 
				
			||||||
 | 
					                    {% if messages %}
 | 
				
			||||||
 | 
					                        <div class="alert alert-warning">
 | 
				
			||||||
 | 
					                            {% for message in messages %}
 | 
				
			||||||
 | 
					                            <span>{{ message }}</span>
 | 
				
			||||||
 | 
					                            {% endfor %}
 | 
				
			||||||
 | 
					                        </div>
 | 
				
			||||||
 | 
					                    {% endif %}
 | 
				
			||||||
 | 
					                </div>
 | 
				
			||||||
				<thead> 
 | 
									<thead> 
 | 
				
			||||||
				<tr> 
 | 
									<tr> 
 | 
				
			||||||
					<th>{% trans "ID"%}</th>
 | 
										<th>{% trans "ID"%}</th>
 | 
				
			||||||
| 
						 | 
					@ -28,7 +38,7 @@
 | 
				
			||||||
                           
 | 
					                           
 | 
				
			||||||
							{% if vm.state == 'ACTIVE' %}
 | 
												{% if vm.state == 'ACTIVE' %}
 | 
				
			||||||
								<span class="h3 label label-success"><strong> {{vm.state}}</strong></span>
 | 
													<span class="h3 label label-success"><strong> {{vm.state}}</strong></span>
 | 
				
			||||||
							{% elif  vm.state == 'POWEROFF' %}
 | 
												{% elif  vm.state == 'FAILED' %}
 | 
				
			||||||
								<span class="h3 label label-danger"><strong>{{vm.state}}</strong></span>
 | 
													<span class="h3 label label-danger"><strong>{{vm.state}}</strong></span>
 | 
				
			||||||
							{% else %}
 | 
												{% else %}
 | 
				
			||||||
								<span class="h3 label label-warning"><strong>{{vm.state}}</strong></span>
 | 
													<span class="h3 label label-warning"><strong>{{vm.state}}</strong></span>
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										255
									
								
								hosting/views.py
									
										
									
									
									
								
							
							
						
						
									
										255
									
								
								hosting/views.py
									
										
									
									
									
								
							| 
						 | 
					@ -11,7 +11,8 @@ from django.contrib.auth import authenticate, login
 | 
				
			||||||
from django.contrib import messages
 | 
					from django.contrib import messages
 | 
				
			||||||
from django.conf import settings
 | 
					from django.conf import settings
 | 
				
			||||||
from django.shortcuts import redirect
 | 
					from django.shortcuts import redirect
 | 
				
			||||||
 | 
					from django.utils.http import urlsafe_base64_decode
 | 
				
			||||||
 | 
					from django.contrib.auth.tokens import default_token_generator
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from guardian.mixins import PermissionRequiredMixin
 | 
					from guardian.mixins import PermissionRequiredMixin
 | 
				
			||||||
from stored_messages.settings import stored_messages_settings
 | 
					from stored_messages.settings import stored_messages_settings
 | 
				
			||||||
| 
						 | 
					@ -21,7 +22,7 @@ from stored_messages.api import mark_read
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from membership.models import CustomUser, StripeCustomer
 | 
					from membership.models import CustomUser, StripeCustomer
 | 
				
			||||||
from utils.stripe_utils import StripeUtils
 | 
					from utils.stripe_utils import StripeUtils
 | 
				
			||||||
from utils.forms import BillingAddressForm, PasswordResetRequestForm
 | 
					from utils.forms import BillingAddressForm, PasswordResetRequestForm, UserBillingAddressForm
 | 
				
			||||||
from utils.views import PasswordResetViewMixin, PasswordResetConfirmViewMixin, LoginViewMixin
 | 
					from utils.views import PasswordResetViewMixin, PasswordResetConfirmViewMixin, LoginViewMixin
 | 
				
			||||||
from utils.mailer import BaseEmail
 | 
					from utils.mailer import BaseEmail
 | 
				
			||||||
from .models import HostingOrder, HostingBill, UserHostingKey
 | 
					from .models import HostingOrder, HostingBill, UserHostingKey
 | 
				
			||||||
| 
						 | 
					@ -162,7 +163,7 @@ class SignupView(CreateView):
 | 
				
			||||||
    model = CustomUser
 | 
					    model = CustomUser
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def get_success_url(self):
 | 
					    def get_success_url(self):
 | 
				
			||||||
        next_url = self.request.session.get('next', reverse_lazy('hosting:signup'))
 | 
					        next_url = self.request.session.get('next', reverse_lazy('hosting:virtual_machines'))
 | 
				
			||||||
        return next_url
 | 
					        return next_url
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def form_valid(self, form):
 | 
					    def form_valid(self, form):
 | 
				
			||||||
| 
						 | 
					@ -188,6 +189,43 @@ class PasswordResetConfirmView(PasswordResetConfirmViewMixin):
 | 
				
			||||||
    template_name = 'hosting/confirm_reset_password.html'
 | 
					    template_name = 'hosting/confirm_reset_password.html'
 | 
				
			||||||
    success_url = reverse_lazy('hosting:login')
 | 
					    success_url = reverse_lazy('hosting:login')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def post(self, request, uidb64=None, token=None, *arg, **kwargs):
 | 
				
			||||||
 | 
					        try:
 | 
				
			||||||
 | 
					            uid = urlsafe_base64_decode(uidb64)
 | 
				
			||||||
 | 
					            user = CustomUser.objects.get(pk=uid)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            opennebula_client = OpenNebulaManager(
 | 
				
			||||||
 | 
					                email=user.email,
 | 
				
			||||||
 | 
					                password=user.password,
 | 
				
			||||||
 | 
					            )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        except (TypeError, ValueError, OverflowError, CustomUser.DoesNotExist):
 | 
				
			||||||
 | 
					            user = None
 | 
				
			||||||
 | 
					            opennebula_client = None
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        form = self.form_class(request.POST)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if user is not None and default_token_generator.check_token(user, token):
 | 
				
			||||||
 | 
					            if form.is_valid():
 | 
				
			||||||
 | 
					                new_password = form.cleaned_data['new_password2']
 | 
				
			||||||
 | 
					                user.set_password(new_password)
 | 
				
			||||||
 | 
					                user.save()
 | 
				
			||||||
 | 
					                messages.success(request, 'Password has been reset.')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                # Change opennebula password
 | 
				
			||||||
 | 
					                opennebula_client.change_user_password(new_password)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                return self.form_valid(form)
 | 
				
			||||||
 | 
					            else:
 | 
				
			||||||
 | 
					                messages.error(request, 'Password reset has not been successful.')
 | 
				
			||||||
 | 
					                form.add_error(None, 'Password reset has not been successful.')
 | 
				
			||||||
 | 
					                return self.form_invalid(form)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        else:
 | 
				
			||||||
 | 
					            messages.error(request, 'The reset password link is no longer valid.')
 | 
				
			||||||
 | 
					            form.add_error(None, 'The reset password link is no longer valid.')
 | 
				
			||||||
 | 
					            return self.form_invalid(form)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class NotificationsView(LoginRequiredMixin, TemplateView):
 | 
					class NotificationsView(LoginRequiredMixin, TemplateView):
 | 
				
			||||||
    template_name = 'hosting/notifications.html'
 | 
					    template_name = 'hosting/notifications.html'
 | 
				
			||||||
| 
						 | 
					@ -228,18 +266,19 @@ class GenerateVMSSHKeysView(LoginRequiredMixin, FormView):
 | 
				
			||||||
    context_object_name = "virtual_machine"
 | 
					    context_object_name = "virtual_machine"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def get_context_data(self, **kwargs):
 | 
					    def get_context_data(self, **kwargs):
 | 
				
			||||||
        try:
 | 
					 | 
				
			||||||
            user_key = UserHostingKey.objects.get(
 | 
					 | 
				
			||||||
                user=self.request.user
 | 
					 | 
				
			||||||
            )
 | 
					 | 
				
			||||||
        except UserHostingKey.DoesNotExist:
 | 
					 | 
				
			||||||
            user_key = None
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        context = super(
 | 
					        context = super(
 | 
				
			||||||
            GenerateVMSSHKeysView,
 | 
					            GenerateVMSSHKeysView,
 | 
				
			||||||
            self
 | 
					            self
 | 
				
			||||||
        ).get_context_data(**kwargs)
 | 
					        ).get_context_data(**kwargs)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        try:
 | 
				
			||||||
 | 
					            user_key = UserHostingKey.objects.get(
 | 
				
			||||||
 | 
					                user=self.request.user
 | 
				
			||||||
 | 
					            )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        except UserHostingKey.DoesNotExist:
 | 
				
			||||||
 | 
					            user_key = None
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        context.update({
 | 
					        context.update({
 | 
				
			||||||
            'user_key': user_key
 | 
					            'user_key': user_key
 | 
				
			||||||
        })
 | 
					        })
 | 
				
			||||||
| 
						 | 
					@ -258,36 +297,102 @@ class GenerateVMSSHKeysView(LoginRequiredMixin, FormView):
 | 
				
			||||||
        if form.cleaned_data.get('private_key'):
 | 
					        if form.cleaned_data.get('private_key'):
 | 
				
			||||||
            context.update({
 | 
					            context.update({
 | 
				
			||||||
                'private_key': form.cleaned_data.get('private_key'),
 | 
					                'private_key': form.cleaned_data.get('private_key'),
 | 
				
			||||||
                'key_name': form.cleaned_data.get('name')
 | 
					                'key_name': form.cleaned_data.get('name'),
 | 
				
			||||||
 | 
					                'form': UserHostingKeyForm(request=self.request)
 | 
				
			||||||
            })
 | 
					            })
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # print("form", form.cleaned_data)
 | 
					        # return HttpResponseRedirect(reverse('hosting:key_pair'))
 | 
				
			||||||
 | 
					 | 
				
			||||||
        return render(self.request, self.template_name, context)
 | 
					        return render(self.request, self.template_name, context)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def post(self, request, *args, **kwargs):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        try:
 | 
				
			||||||
 | 
					            UserHostingKey.objects.get(
 | 
				
			||||||
 | 
					                user=self.request.user
 | 
				
			||||||
 | 
					            )
 | 
				
			||||||
 | 
					            return HttpResponseRedirect(reverse('hosting:key_pair'))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        except UserHostingKey.DoesNotExist:
 | 
				
			||||||
 | 
					            pass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        form = self.get_form()
 | 
				
			||||||
 | 
					        if form.is_valid():
 | 
				
			||||||
 | 
					            return self.form_valid(form)
 | 
				
			||||||
 | 
					        else:
 | 
				
			||||||
 | 
					            return self.form_invalid(form)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class PaymentVMView(LoginRequiredMixin, FormView):
 | 
					class PaymentVMView(LoginRequiredMixin, FormView):
 | 
				
			||||||
    template_name = 'hosting/payment.html'
 | 
					    template_name = 'hosting/payment.html'
 | 
				
			||||||
    login_url = reverse_lazy('hosting:login')
 | 
					    login_url = reverse_lazy('hosting:login')
 | 
				
			||||||
    form_class = BillingAddressForm
 | 
					    form_class = BillingAddressForm
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def get_form_kwargs(self):
 | 
				
			||||||
 | 
					        current_billing_address = self.request.user.billing_addresses.first()
 | 
				
			||||||
 | 
					        form_kwargs = super(PaymentVMView, self).get_form_kwargs()
 | 
				
			||||||
 | 
					        if not current_billing_address:
 | 
				
			||||||
 | 
					            return form_kwargs
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        form_kwargs.update({
 | 
				
			||||||
 | 
					            'initial': {
 | 
				
			||||||
 | 
					                'street_address': current_billing_address.street_address,
 | 
				
			||||||
 | 
					                'city': current_billing_address.city,
 | 
				
			||||||
 | 
					                'postal_code': current_billing_address.postal_code,
 | 
				
			||||||
 | 
					                'country': current_billing_address.country,
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        })
 | 
				
			||||||
 | 
					        return form_kwargs
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def get_context_data(self, **kwargs):
 | 
					    def get_context_data(self, **kwargs):
 | 
				
			||||||
        context = super(PaymentVMView, self).get_context_data(**kwargs)
 | 
					        context = super(PaymentVMView, self).get_context_data(**kwargs)
 | 
				
			||||||
 | 
					        # Get user
 | 
				
			||||||
 | 
					        user = self.request.user
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # Get user last order
 | 
				
			||||||
 | 
					        last_hosting_order = HostingOrder.objects.filter(customer__user=user).last()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # If user has already an hosting order, get the credit card data from it
 | 
				
			||||||
 | 
					        if last_hosting_order:
 | 
				
			||||||
 | 
					            credit_card_data = last_hosting_order.get_cc_data()
 | 
				
			||||||
 | 
					            context.update({
 | 
				
			||||||
 | 
					                'credit_card_data': credit_card_data if credit_card_data else None,
 | 
				
			||||||
 | 
					            })
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        context.update({
 | 
					        context.update({
 | 
				
			||||||
            'stripe_key': settings.STRIPE_API_PUBLIC_KEY
 | 
					            'stripe_key': settings.STRIPE_API_PUBLIC_KEY
 | 
				
			||||||
        })
 | 
					        })
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return context
 | 
					        return context
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def get(self, request, *args, **kwargs):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        try:
 | 
				
			||||||
 | 
					            UserHostingKey.objects.get(
 | 
				
			||||||
 | 
					                user=self.request.user
 | 
				
			||||||
 | 
					            )
 | 
				
			||||||
 | 
					        except UserHostingKey.DoesNotExist:
 | 
				
			||||||
 | 
					            messages.success(
 | 
				
			||||||
 | 
					                request,
 | 
				
			||||||
 | 
					                'In order to create a VM, you create/upload your SSH KEY first.'
 | 
				
			||||||
 | 
					            )
 | 
				
			||||||
 | 
					            return HttpResponseRedirect(reverse('hosting:key_pair'))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return self.render_to_response(self.get_context_data())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def post(self, request, *args, **kwargs):
 | 
					    def post(self, request, *args, **kwargs):
 | 
				
			||||||
        form = self.get_form()
 | 
					        form = self.get_form()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if form.is_valid():
 | 
					        if form.is_valid():
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            # Get billing address data
 | 
				
			||||||
 | 
					            billing_address_data = form.cleaned_data
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            context = self.get_context_data()
 | 
					            context = self.get_context_data()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            specifications = request.session.get('template')
 | 
					            specifications = request.session.get('template')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            vm_template_id = specifications.get('id', 1)
 | 
					            vm_template_id = specifications.get('id', 1)
 | 
				
			||||||
            
 | 
					
 | 
				
			||||||
            final_price = specifications.get('price', 1)
 | 
					            final_price = specifications.get('price', 1)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            token = form.cleaned_data.get('token')
 | 
					            token = form.cleaned_data.get('token')
 | 
				
			||||||
| 
						 | 
					@ -320,21 +425,46 @@ class PaymentVMView(LoginRequiredMixin, FormView):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            charge = charge_response.get('response_object')
 | 
					            charge = charge_response.get('response_object')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            # Create OpenNebulaManager 
 | 
					            # Create OpenNebulaManager
 | 
				
			||||||
            
 | 
					 | 
				
			||||||
            manager = OpenNebulaManager(email=owner.email,
 | 
					            manager = OpenNebulaManager(email=owner.email,
 | 
				
			||||||
                                        password=owner.password[0:20],
 | 
					                                        password=owner.password,
 | 
				
			||||||
                                        create_user=True)
 | 
					                                        create_user=True)
 | 
				
			||||||
            template = manager.get_template(vm_template_id)
 | 
					            template = manager.get_template(vm_template_id)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            # Get user ssh key
 | 
				
			||||||
 | 
					            try:
 | 
				
			||||||
 | 
					                user_key = UserHostingKey.objects.get(
 | 
				
			||||||
 | 
					                    user=self.request.user
 | 
				
			||||||
 | 
					                )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            except UserHostingKey.DoesNotExist:
 | 
				
			||||||
 | 
					                pass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            # Create a vm using logged user
 | 
					            # Create a vm using logged user
 | 
				
			||||||
            vm_id = manager.create_vm(vm_template_id)
 | 
					            vm_id = manager.create_vm(
 | 
				
			||||||
 | 
					                vm_template_id,
 | 
				
			||||||
 | 
					                ssh_key=user_key.public_key
 | 
				
			||||||
 | 
					            )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            # Create a Hosting Order
 | 
					            # Create a Hosting Order
 | 
				
			||||||
            order = HostingOrder.create(vm_id=vm_id, customer=customer,
 | 
					            order = HostingOrder.create(
 | 
				
			||||||
                                        billing_address=billing_address)
 | 
					                price=final_price,
 | 
				
			||||||
 | 
					                vm_id=vm_id,
 | 
				
			||||||
 | 
					                customer=customer,
 | 
				
			||||||
 | 
					                billing_address=billing_address
 | 
				
			||||||
 | 
					            )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            # Create a Hosting Bill
 | 
					            # Create a Hosting Bill
 | 
				
			||||||
            bill = HostingBill.create(customer=customer, billing_address=billing_address)
 | 
					            bill = HostingBill.create(customer=customer, billing_address=billing_address)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            # Create Billing Address for User if he does not have one
 | 
				
			||||||
 | 
					            if not customer.user.billing_addresses.count():
 | 
				
			||||||
 | 
					                billing_address_data.update({
 | 
				
			||||||
 | 
					                    'user': customer.user.id
 | 
				
			||||||
 | 
					                })
 | 
				
			||||||
 | 
					                billing_address_user_form = UserBillingAddressForm(billing_address_data)
 | 
				
			||||||
 | 
					                billing_address_user_form.is_valid()
 | 
				
			||||||
 | 
					                billing_address_user_form.save()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            # Associate an order with a stripe payment
 | 
					            # Associate an order with a stripe payment
 | 
				
			||||||
            order.set_stripe_charge(charge)
 | 
					            order.set_stripe_charge(charge)
 | 
				
			||||||
| 
						 | 
					@ -344,7 +474,6 @@ class PaymentVMView(LoginRequiredMixin, FormView):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            vm = VirtualMachineSerializer(manager.get_vm(vm_id)).data
 | 
					            vm = VirtualMachineSerializer(manager.get_vm(vm_id)).data
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
            # Send notification to ungleich as soon as VM has been booked
 | 
					            # Send notification to ungleich as soon as VM has been booked
 | 
				
			||||||
            context = {
 | 
					            context = {
 | 
				
			||||||
                'vm': vm,
 | 
					                'vm': vm,
 | 
				
			||||||
| 
						 | 
					@ -380,10 +509,11 @@ class OrdersHostingDetailView(PermissionRequiredMixin, LoginRequiredMixin, Detai
 | 
				
			||||||
        obj = self.get_object()
 | 
					        obj = self.get_object()
 | 
				
			||||||
        owner = self.request.user
 | 
					        owner = self.request.user
 | 
				
			||||||
        manager = OpenNebulaManager(email=owner.email,
 | 
					        manager = OpenNebulaManager(email=owner.email,
 | 
				
			||||||
                                    password=owner.password[0:20],
 | 
					                                    password=owner.password,
 | 
				
			||||||
                                    create_user=True)
 | 
					                                    create_user=True)
 | 
				
			||||||
        vm = manager.get_vm(obj.vm_id)
 | 
					        vm = manager.get_vm(obj.vm_id)
 | 
				
			||||||
        context['vm'] = VirtualMachineSerializer(vm).data
 | 
					        context['vm'] = VirtualMachineSerializer(vm).data
 | 
				
			||||||
 | 
					        return context
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class OrdersHostingListView(LoginRequiredMixin, ListView):
 | 
					class OrdersHostingListView(LoginRequiredMixin, ListView):
 | 
				
			||||||
| 
						 | 
					@ -416,7 +546,7 @@ class VirtualMachinesPlanListView(LoginRequiredMixin, ListView):
 | 
				
			||||||
    def get_queryset(self):
 | 
					    def get_queryset(self):
 | 
				
			||||||
        owner = self.request.user
 | 
					        owner = self.request.user
 | 
				
			||||||
        manager = OpenNebulaManager(email=owner.email,
 | 
					        manager = OpenNebulaManager(email=owner.email,
 | 
				
			||||||
                                    password=owner.password[0:20],
 | 
					                                    password=owner.password,
 | 
				
			||||||
                                    create_user=True)
 | 
					                                    create_user=True)
 | 
				
			||||||
        queryset = manager.get_vms()
 | 
					        queryset = manager.get_vms()
 | 
				
			||||||
        serializer = VirtualMachineSerializer(queryset, many=True)
 | 
					        serializer = VirtualMachineSerializer(queryset, many=True)
 | 
				
			||||||
| 
						 | 
					@ -428,29 +558,33 @@ class CreateVirtualMachinesView(LoginRequiredMixin, View):
 | 
				
			||||||
    login_url = reverse_lazy('hosting:login')
 | 
					    login_url = reverse_lazy('hosting:login')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def get(self, request, *args, **kwargs):
 | 
					    def get(self, request, *args, **kwargs):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        try:
 | 
				
			||||||
 | 
					            UserHostingKey.objects.get(
 | 
				
			||||||
 | 
					                user=self.request.user
 | 
				
			||||||
 | 
					            )
 | 
				
			||||||
 | 
					        except UserHostingKey.DoesNotExist:
 | 
				
			||||||
 | 
					            messages.success(
 | 
				
			||||||
 | 
					                request,
 | 
				
			||||||
 | 
					                'In order to create a VM, you need to create/upload your SSH KEY first.'
 | 
				
			||||||
 | 
					            )
 | 
				
			||||||
 | 
					            return HttpResponseRedirect(reverse('hosting:key_pair'))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        #TODO: Replace with OpenNebulaManager.get_apps
 | 
					        #TODO: Replace with OpenNebulaManager.get_apps
 | 
				
			||||||
        templates = OpenNebulaManager().get_templates()
 | 
					        templates = OpenNebulaManager().get_templates()
 | 
				
			||||||
        data = VirtualMachineTemplateSerializer(templates, many=True).data
 | 
					        data = VirtualMachineTemplateSerializer(templates, many=True).data
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        context = {
 | 
					        context = {
 | 
				
			||||||
            'templates': data,
 | 
					            'templates': data,
 | 
				
			||||||
            #'configuration_options': VirtualMachinePlan.VM_CONFIGURATION
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        # context = {}
 | 
					        # context = {}
 | 
				
			||||||
        return render(request, self.template_name, context)
 | 
					        return render(request, self.template_name, context)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def post(self, request):
 | 
					    def post(self, request):
 | 
				
			||||||
        #XXX: Fix this!
 | 
					 | 
				
			||||||
        #configuration = request.POST.get('configuration')
 | 
					 | 
				
			||||||
        #configuration_display = dict(VirtualMachinePlan.VM_CONFIGURATION).get(configuration)
 | 
					 | 
				
			||||||
        template_id = int(request.POST.get('vm_template_id'))
 | 
					        template_id = int(request.POST.get('vm_template_id'))
 | 
				
			||||||
        template = OpenNebulaManager().get_template(template_id)
 | 
					        template = OpenNebulaManager().get_template(template_id)
 | 
				
			||||||
        data = VirtualMachineTemplateSerializer(template).data
 | 
					        data = VirtualMachineTemplateSerializer(template).data
 | 
				
			||||||
        vm_specs = {
 | 
					        request.session['template'] = data
 | 
				
			||||||
            #'configuration_display': configuration_display,
 | 
					 | 
				
			||||||
            #'configuration': configuration,
 | 
					 | 
				
			||||||
            'template': data, 
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        request.session['template'] = data 
 | 
					 | 
				
			||||||
        return redirect(reverse('hosting:payment'))
 | 
					        return redirect(reverse('hosting:payment'))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -458,28 +592,56 @@ class VirtualMachineView(LoginRequiredMixin, View):
 | 
				
			||||||
    template_name = "hosting/virtual_machine_detail.html"
 | 
					    template_name = "hosting/virtual_machine_detail.html"
 | 
				
			||||||
    login_url = reverse_lazy('hosting:login')
 | 
					    login_url = reverse_lazy('hosting:login')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def get(self, request, *args, **kwargs):
 | 
					    def get_object(self):
 | 
				
			||||||
        owner = self.request.user
 | 
					        owner = self.request.user
 | 
				
			||||||
        manager = OpenNebulaManager(email=owner.email,
 | 
					        vm = None
 | 
				
			||||||
                                    password=owner.password[0:20],
 | 
					        manager = OpenNebulaManager(
 | 
				
			||||||
                                    create_user=True)
 | 
					            email=owner.email,
 | 
				
			||||||
 | 
					            password=owner.password,
 | 
				
			||||||
 | 
					            create_user=True
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
        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)
 | 
				
			||||||
            serializer = VirtualMachineSerializer(vm)
 | 
					 | 
				
			||||||
        except Exception as error:
 | 
					        except Exception as error:
 | 
				
			||||||
            print(error)
 | 
					            print(error)
 | 
				
			||||||
            raise Http404()
 | 
					            raise Http404()
 | 
				
			||||||
 | 
					        return vm
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def get_success_url(self):
 | 
				
			||||||
 | 
					        final_url = reverse('hosting:virtual_machines')
 | 
				
			||||||
 | 
					        return final_url
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def get(self, request, *args, **kwargs):
 | 
				
			||||||
 | 
					        vm = self.get_object()
 | 
				
			||||||
 | 
					        serializer = VirtualMachineSerializer(vm)
 | 
				
			||||||
        context = {
 | 
					        context = {
 | 
				
			||||||
            'virtual_machine': serializer.data,
 | 
					            'virtual_machine': serializer.data,
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        return render(request, self.template_name, context)
 | 
					        return render(request, self.template_name, context)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def post(self, *args, **kwargs):
 | 
					    def post(self, request, *args, **kwargs):
 | 
				
			||||||
        #TODO: add api to OpenNebulaManager
 | 
					        owner = self.request.user
 | 
				
			||||||
        vm = self.get_object()
 | 
					        vm = self.get_object()
 | 
				
			||||||
        vm.cancel_plan()
 | 
					
 | 
				
			||||||
 | 
					        opennebula_vm_id = self.kwargs.get('pk')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        manager = OpenNebulaManager(
 | 
				
			||||||
 | 
					            email=owner.email,
 | 
				
			||||||
 | 
					            password=owner.password,
 | 
				
			||||||
 | 
					            create_user=True
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        terminated = manager.delete_vm(
 | 
				
			||||||
 | 
					            vm.id
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if not terminated:
 | 
				
			||||||
 | 
					            messages.error(
 | 
				
			||||||
 | 
					                request,
 | 
				
			||||||
 | 
					                'Error terminating VM %s' % (opennebula_vm_id)
 | 
				
			||||||
 | 
					            )
 | 
				
			||||||
 | 
					            return HttpResponseRedirect(self.get_success_url())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        context = {
 | 
					        context = {
 | 
				
			||||||
            'vm': vm,
 | 
					            'vm': vm,
 | 
				
			||||||
| 
						 | 
					@ -495,8 +657,14 @@ class VirtualMachineView(LoginRequiredMixin, View):
 | 
				
			||||||
        email = BaseEmail(**email_data)
 | 
					        email = BaseEmail(**email_data)
 | 
				
			||||||
        email.send()
 | 
					        email.send()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        messages.error(
 | 
				
			||||||
 | 
					            request,
 | 
				
			||||||
 | 
					            'VM %s terminated successfully' % (opennebula_vm_id)
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return HttpResponseRedirect(self.get_success_url())
 | 
					        return HttpResponseRedirect(self.get_success_url())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class HostingBillListView(LoginRequiredMixin, ListView):
 | 
					class HostingBillListView(LoginRequiredMixin, ListView):
 | 
				
			||||||
    template_name = "hosting/bills.html"
 | 
					    template_name = "hosting/bills.html"
 | 
				
			||||||
    login_url = reverse_lazy('hosting:login')
 | 
					    login_url = reverse_lazy('hosting:login')
 | 
				
			||||||
| 
						 | 
					@ -505,6 +673,7 @@ class HostingBillListView(LoginRequiredMixin, ListView):
 | 
				
			||||||
    paginate_by = 10
 | 
					    paginate_by = 10
 | 
				
			||||||
    ordering = '-id'
 | 
					    ordering = '-id'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class HostingBillDetailView(PermissionRequiredMixin, LoginRequiredMixin, DetailView):
 | 
					class HostingBillDetailView(PermissionRequiredMixin, LoginRequiredMixin, DetailView):
 | 
				
			||||||
    template_name = "hosting/bill_detail.html"
 | 
					    template_name = "hosting/bill_detail.html"
 | 
				
			||||||
    login_url = reverse_lazy('hosting:login')
 | 
					    login_url = reverse_lazy('hosting:login')
 | 
				
			||||||
| 
						 | 
					@ -513,7 +682,7 @@ class HostingBillDetailView(PermissionRequiredMixin, LoginRequiredMixin, DetailV
 | 
				
			||||||
    model = HostingBill
 | 
					    model = HostingBill
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def get_object(self, queryset=None):
 | 
					    def get_object(self, queryset=None):
 | 
				
			||||||
        #Get HostingBill for primary key (Select from customer users)
 | 
					        # Get HostingBill for primary key (Select from customer users)
 | 
				
			||||||
        pk = self.kwargs['pk']
 | 
					        pk = self.kwargs['pk']
 | 
				
			||||||
        object = HostingBill.objects.filter(customer__id=pk).first()
 | 
					        object = HostingBill.objects.filter(customer__id=pk).first()
 | 
				
			||||||
        if object is None:
 | 
					        if object is None:
 | 
				
			||||||
| 
						 | 
					@ -526,7 +695,7 @@ class HostingBillDetailView(PermissionRequiredMixin, LoginRequiredMixin, DetailV
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        owner = self.request.user
 | 
					        owner = self.request.user
 | 
				
			||||||
        manager = OpenNebulaManager(email=owner.email,
 | 
					        manager = OpenNebulaManager(email=owner.email,
 | 
				
			||||||
                                    password=owner.password[0:20],
 | 
					                                    password=owner.password,
 | 
				
			||||||
                                    create_user=True)
 | 
					                                    create_user=True)
 | 
				
			||||||
        # Get vms
 | 
					        # Get vms
 | 
				
			||||||
        queryset = manager.get_vms()
 | 
					        queryset = manager.get_vms()
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,10 +1,14 @@
 | 
				
			||||||
import oca
 | 
					import oca
 | 
				
			||||||
import socket
 | 
					import socket
 | 
				
			||||||
 | 
					import logging
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from django.conf import settings
 | 
					from django.conf import settings
 | 
				
			||||||
from django.utils.functional import cached_property
 | 
					from django.utils.functional import cached_property
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from oca.pool import WrongNameError
 | 
					from oca.pool import WrongNameError
 | 
				
			||||||
 | 
					from oca.exceptions import OpenNebulaException
 | 
				
			||||||
 | 
					logger = logging.getLogger(__name__)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class OpenNebulaManager():
 | 
					class OpenNebulaManager():
 | 
				
			||||||
    """This class represents an opennebula manager."""
 | 
					    """This class represents an opennebula manager."""
 | 
				
			||||||
| 
						 | 
					@ -99,14 +103,17 @@ class OpenNebulaManager():
 | 
				
			||||||
        return vm_pool.get_by_id(int(vm_id))
 | 
					        return vm_pool.get_by_id(int(vm_id))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    #TODO: get app with id 
 | 
					    #TODO: get app with id 
 | 
				
			||||||
    def create_vm(self, template_id, app_id=None):
 | 
					    def create_vm(self, template_id, app_id=None, ssh_key=None):
 | 
				
			||||||
 | 
					        extra_template = "<CONTEXT><SSH_PUBLIC_KEY>{ssh_key}</SSH_PUBLIC_KEY></CONTEXT>".format(
 | 
				
			||||||
 | 
					            ssh_key=ssh_key
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
        vm_id = self.oneadmin_client.call(
 | 
					        vm_id = self.oneadmin_client.call(
 | 
				
			||||||
                    oca.VmTemplate.METHODS['instantiate'],
 | 
					            oca.VmTemplate.METHODS['instantiate'],
 | 
				
			||||||
                    template_id,
 | 
					            template_id,
 | 
				
			||||||
                    '',
 | 
					            '',
 | 
				
			||||||
                    False,
 | 
					            False,
 | 
				
			||||||
                    ''
 | 
					            extra_template
 | 
				
			||||||
                )
 | 
					        )
 | 
				
			||||||
        try:
 | 
					        try:
 | 
				
			||||||
            self.oneadmin_client.call(
 | 
					            self.oneadmin_client.call(
 | 
				
			||||||
                oca.VirtualMachine.METHODS['chown'],
 | 
					                oca.VirtualMachine.METHODS['chown'],
 | 
				
			||||||
| 
						 | 
					@ -119,11 +126,29 @@ class OpenNebulaManager():
 | 
				
			||||||
        return vm_id
 | 
					        return vm_id
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def delete_vm(self, vm_id):
 | 
					    def delete_vm(self, vm_id):
 | 
				
			||||||
        self.oneadmin_client.call(
 | 
					        TERMINATE_ACTION = 'terminate'
 | 
				
			||||||
                oca.VirtualMachine.METHODS['action'], 
 | 
					        vm_terminated = False
 | 
				
			||||||
                'terminate',
 | 
					        try:
 | 
				
			||||||
                int(vm_id)
 | 
					            self.oneadmin_client.call(
 | 
				
			||||||
                )
 | 
					                oca.VirtualMachine.METHODS['action'],
 | 
				
			||||||
 | 
					                TERMINATE_ACTION,
 | 
				
			||||||
 | 
					                int(vm_id),
 | 
				
			||||||
 | 
					            )
 | 
				
			||||||
 | 
					            vm_terminated = True
 | 
				
			||||||
 | 
					        except socket.timeout as socket_err:
 | 
				
			||||||
 | 
					            logger.info("Socket timeout error: {0}".format(socket_err))
 | 
				
			||||||
 | 
					            print("Socket timeout error: {0}".format(socket_err))
 | 
				
			||||||
 | 
					        except OpenNebulaException as opennebula_err:
 | 
				
			||||||
 | 
					            logger.info("OpenNebulaException error: {0}".format(opennebula_err))
 | 
				
			||||||
 | 
					            print("OpenNebulaException error: {0}".format(opennebula_err))
 | 
				
			||||||
 | 
					        except OSError as os_err:
 | 
				
			||||||
 | 
					            logger.info("OSError : {0}".format(os_err))
 | 
				
			||||||
 | 
					            print("OSError : {0}".format(os_err))
 | 
				
			||||||
 | 
					        except ValueError as value_err:
 | 
				
			||||||
 | 
					            logger.info("ValueError : {0}".format(value_err))
 | 
				
			||||||
 | 
					            print("ValueError : {0}".format(value_err))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return vm_terminated
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def _get_template_pool(self):
 | 
					    def _get_template_pool(self):
 | 
				
			||||||
        try:
 | 
					        try:
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -91,7 +91,7 @@ class VirtualMachineSerializer(serializers.Serializer):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        try:
 | 
					        try:
 | 
				
			||||||
            manager = OpenNebulaManager(email=owner.email,
 | 
					            manager = OpenNebulaManager(email=owner.email,
 | 
				
			||||||
                                        password=owner.password[0:20],
 | 
					                                        password=owner.password,
 | 
				
			||||||
                                        create_user = True)
 | 
					                                        create_user = True)
 | 
				
			||||||
            opennebula_id = manager.create_vm(template_id)
 | 
					            opennebula_id = manager.create_vm(template_id)
 | 
				
			||||||
        except OpenNebulaException as err:
 | 
					        except OpenNebulaException as err:
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -47,7 +47,7 @@ class VmCreateView(generics.ListCreateAPIView):
 | 
				
			||||||
    def get_queryset(self):
 | 
					    def get_queryset(self):
 | 
				
			||||||
        owner = self.request.user
 | 
					        owner = self.request.user
 | 
				
			||||||
        manager = OpenNebulaManager(email=owner.email,
 | 
					        manager = OpenNebulaManager(email=owner.email,
 | 
				
			||||||
                                    password=owner.password[0:20],
 | 
					                                    password=owner.password,
 | 
				
			||||||
                                    create_user=True)
 | 
					                                    create_user=True)
 | 
				
			||||||
        return manager.get_vms()
 | 
					        return manager.get_vms()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -64,21 +64,21 @@ class VmDetailsView(generics.RetrieveUpdateDestroyAPIView):
 | 
				
			||||||
    def get_queryset(self):
 | 
					    def get_queryset(self):
 | 
				
			||||||
        owner = self.request.user
 | 
					        owner = self.request.user
 | 
				
			||||||
        manager = OpenNebulaManager(email=owner.email,
 | 
					        manager = OpenNebulaManager(email=owner.email,
 | 
				
			||||||
                                    password=owner.password[0:20],
 | 
					                                    password=owner.password,
 | 
				
			||||||
                                    create_user=True)
 | 
					                                    create_user=True)
 | 
				
			||||||
        return manager.get_vms()
 | 
					        return manager.get_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[0:20],
 | 
					                                    password=owner.password,
 | 
				
			||||||
                                    create_user=True)
 | 
					                                    create_user=True)
 | 
				
			||||||
        return manager.get_vm(self.kwargs.get('pk'))
 | 
					        return manager.get_vm(self.kwargs.get('pk'))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    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[0:20],
 | 
					                                    password=owner.password,
 | 
				
			||||||
                                    create_user = True)
 | 
					                                    create_user = True)
 | 
				
			||||||
        manager.delete_vm(instance.id)
 | 
					        manager.delete_vm(instance.id)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -100,7 +100,7 @@ class EditCreditCardForm(forms.Form):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class BillingAddressForm(forms.ModelForm):
 | 
					class BillingAddressForm(forms.ModelForm):
 | 
				
			||||||
    token = forms.CharField(widget=forms.HiddenInput())
 | 
					    token = forms.CharField(widget=forms.HiddenInput(), required=False)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    class Meta:
 | 
					    class Meta:
 | 
				
			||||||
        model = BillingAddress
 | 
					        model = BillingAddress
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue