Merge pull request #500 from pcoder/task/3764/show_cancelled_vms_my_orders
Task/3764/show cancelled vms my orders
This commit is contained in:
		
				commit
				
					
						a0eada2e77
					
				
			
		
					 6 changed files with 124 additions and 26 deletions
				
			
		|  | @ -13,7 +13,7 @@ from hosting.models import HostingOrder, HostingBill | ||||||
| from membership.models import StripeCustomer, CustomUser | from membership.models import StripeCustomer, CustomUser | ||||||
| from opennebula_api.models import OpenNebulaManager | from opennebula_api.models import OpenNebulaManager | ||||||
| from opennebula_api.serializers import VirtualMachineSerializer | from opennebula_api.serializers import VirtualMachineSerializer | ||||||
| from utils.hosting_utils import get_all_public_keys | from utils.hosting_utils import get_all_public_keys, get_or_create_vm_detail | ||||||
| from utils.forms import UserBillingAddressForm | from utils.forms import UserBillingAddressForm | ||||||
| from utils.mailer import BaseEmail | from utils.mailer import BaseEmail | ||||||
| from utils.models import BillingAddress | from utils.models import BillingAddress | ||||||
|  | @ -174,6 +174,7 @@ def create_vm_task(self, vm_template_id, user, specs, template, | ||||||
|             logger.debug("New VM ID is {vm_id}".format(vm_id=vm_id)) |             logger.debug("New VM ID is {vm_id}".format(vm_id=vm_id)) | ||||||
|             if new_host is not None: |             if new_host is not None: | ||||||
|                 custom_user = CustomUser.objects.get(email=user.get('email')) |                 custom_user = CustomUser.objects.get(email=user.get('email')) | ||||||
|  |                 get_or_create_vm_detail(custom_user, manager, vm_id) | ||||||
|                 if custom_user is not None: |                 if custom_user is not None: | ||||||
|                     public_keys = get_all_public_keys(custom_user) |                     public_keys = get_all_public_keys(custom_user) | ||||||
|                     keys = [{'value': key, 'state': True} for key in |                     keys = [{'value': key, 'state': True} for key in | ||||||
|  |  | ||||||
							
								
								
									
										34
									
								
								hosting/migrations/0043_vmdetail.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								hosting/migrations/0043_vmdetail.py
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,34 @@ | ||||||
|  | # -*- coding: utf-8 -*- | ||||||
|  | # Generated by Django 1.9.4 on 2017-09-24 18:12 | ||||||
|  | from __future__ import unicode_literals | ||||||
|  | 
 | ||||||
|  | from django.conf import settings | ||||||
|  | from django.db import migrations, models | ||||||
|  | import django.db.models.deletion | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | class Migration(migrations.Migration): | ||||||
|  | 
 | ||||||
|  |     dependencies = [ | ||||||
|  |         migrations.swappable_dependency(settings.AUTH_USER_MODEL), | ||||||
|  |         ('hosting', '0042_hostingorder_subscription_id'), | ||||||
|  |     ] | ||||||
|  | 
 | ||||||
|  |     operations = [ | ||||||
|  |         migrations.CreateModel( | ||||||
|  |             name='VMDetail', | ||||||
|  |             fields=[ | ||||||
|  |                 ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), | ||||||
|  |                 ('vm_id', models.IntegerField(default=0)), | ||||||
|  |                 ('disk_size', models.FloatField(default=0.0)), | ||||||
|  |                 ('cores', models.FloatField(default=0.0)), | ||||||
|  |                 ('memory', models.FloatField(default=0.0)), | ||||||
|  |                 ('configuration', models.CharField(default='', max_length=25)), | ||||||
|  |                 ('ipv4', models.TextField(default='')), | ||||||
|  |                 ('ipv6', models.TextField(default='')), | ||||||
|  |                 ('created_at', models.DateTimeField(auto_now_add=True)), | ||||||
|  |                 ('terminated_at', models.DateTimeField(null=True)), | ||||||
|  |                 ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), | ||||||
|  |             ], | ||||||
|  |         ), | ||||||
|  |     ] | ||||||
|  | @ -159,3 +159,16 @@ class HostingBill(AssignPermissionsMixin, models.Model): | ||||||
|         instance = cls.objects.create(customer=customer, |         instance = cls.objects.create(customer=customer, | ||||||
|                                       billing_address=billing_address) |                                       billing_address=billing_address) | ||||||
|         return instance |         return instance | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | class VMDetail(models.Model): | ||||||
|  |     user = models.ForeignKey(CustomUser) | ||||||
|  |     vm_id = models.IntegerField(default=0) | ||||||
|  |     disk_size = models.FloatField(default=0.0) | ||||||
|  |     cores = models.FloatField(default=0.0) | ||||||
|  |     memory = models.FloatField(default=0.0) | ||||||
|  |     configuration = models.CharField(default='', max_length=25) | ||||||
|  |     ipv4 = models.TextField(default='') | ||||||
|  |     ipv6 = models.TextField(default='') | ||||||
|  |     created_at = models.DateTimeField(auto_now_add=True) | ||||||
|  |     terminated_at = models.DateTimeField(null=True) | ||||||
|  |  | ||||||
|  | @ -42,7 +42,9 @@ | ||||||
|                 <p> |                 <p> | ||||||
|                     <strong>{% trans "Status" %}: </strong> |                     <strong>{% trans "Status" %}: </strong> | ||||||
|                     <strong> |                     <strong> | ||||||
|                         {% if order.status == 'Approved' %} |                         {% if vm.terminated_at %} | ||||||
|  |                             <span class="vm-color-failed">{% trans "Terminated" %}</span> | ||||||
|  |                         {% elif order.status == 'Approved' %} | ||||||
|                             <span class="vm-color-online">{% trans "Approved" %}</span> |                             <span class="vm-color-online">{% trans "Approved" %}</span> | ||||||
|                         {% else %} |                         {% else %} | ||||||
|                             <span class="vm-status-failed">{% trans "Declined" %}</span> |                             <span class="vm-status-failed">{% trans "Declined" %}</span> | ||||||
|  |  | ||||||
|  | @ -1,6 +1,7 @@ | ||||||
| import json | import json | ||||||
| import logging | import logging | ||||||
| import uuid | import uuid | ||||||
|  | from datetime import datetime | ||||||
| from time import sleep | from time import sleep | ||||||
| 
 | 
 | ||||||
| from django import forms | from django import forms | ||||||
|  | @ -46,10 +47,11 @@ from utils.views import ( | ||||||
| from .forms import HostingUserSignupForm, HostingUserLoginForm, \ | from .forms import HostingUserSignupForm, HostingUserLoginForm, \ | ||||||
|     UserHostingKeyForm, generate_ssh_key_name |     UserHostingKeyForm, generate_ssh_key_name | ||||||
| from .mixins import ProcessVMSelectionMixin | from .mixins import ProcessVMSelectionMixin | ||||||
| from .models import HostingOrder, HostingBill, HostingPlan, UserHostingKey | from .models import ( | ||||||
|  |     HostingOrder, HostingBill, HostingPlan, UserHostingKey, VMDetail | ||||||
|  | ) | ||||||
| from datacenterlight.models import VMTemplate | from datacenterlight.models import VMTemplate | ||||||
| 
 | 
 | ||||||
| 
 |  | ||||||
| logger = logging.getLogger(__name__) | logger = logging.getLogger(__name__) | ||||||
| 
 | 
 | ||||||
| CONNECTION_ERROR = "Your VMs cannot be displayed at the moment due to a \ | CONNECTION_ERROR = "Your VMs cannot be displayed at the moment due to a \ | ||||||
|  | @ -689,25 +691,29 @@ class OrdersHostingDetailView(LoginRequiredMixin, | ||||||
|         if obj is not None: |         if obj is not None: | ||||||
|             # invoice for previous order |             # invoice for previous order | ||||||
|             try: |             try: | ||||||
|                 manager = OpenNebulaManager( |                 vm_detail = VMDetail.objects.get(vm_id=obj.vm_id) | ||||||
|                     email=owner.email, password=owner.password |                 context['vm'] = vm_detail.__dict__ | ||||||
|                 ) |             except VMDetail.DoesNotExist: | ||||||
|                 vm = manager.get_vm(obj.vm_id) |                 try: | ||||||
|                 context['vm'] = VirtualMachineSerializer(vm).data |                     manager = OpenNebulaManager( | ||||||
|             except WrongIdError: |                         email=owner.email, password=owner.password | ||||||
|                 messages.error( |                     ) | ||||||
|                     self.request, |                     vm = manager.get_vm(obj.vm_id) | ||||||
|                     _('The VM you are looking for is unavailable at the ' |                     context['vm'] = VirtualMachineSerializer(vm).data | ||||||
|                       'moment. Please contact Data Center Light support.') |                 except WrongIdError: | ||||||
|                 ) |                     messages.error( | ||||||
|                 self.kwargs['error'] = 'WrongIdError' |                         self.request, | ||||||
|                 context['error'] = 'WrongIdError' |                         _('The VM you are looking for is unavailable at the ' | ||||||
|             except ConnectionRefusedError: |                           'moment. Please contact Data Center Light support.') | ||||||
|                 messages.error( |                     ) | ||||||
|                     self.request, |                     self.kwargs['error'] = 'WrongIdError' | ||||||
|                     _('In order to create a VM, you need to create/upload ' |                     context['error'] = 'WrongIdError' | ||||||
|                       'your SSH KEY first.') |                 except ConnectionRefusedError: | ||||||
|                 ) |                     messages.error( | ||||||
|  |                         self.request, | ||||||
|  |                         _('In order to create a VM, you need to create/upload ' | ||||||
|  |                           'your SSH KEY first.') | ||||||
|  |                     ) | ||||||
|         elif not card_details.get('response_object'): |         elif not card_details.get('response_object'): | ||||||
|             # new order, failed to get card details |             # new order, failed to get card details | ||||||
|             context['failed_payment'] = True |             context['failed_payment'] = True | ||||||
|  | @ -1054,6 +1060,10 @@ class VirtualMachineView(LoginRequiredMixin, View): | ||||||
|                 except WrongIdError: |                 except WrongIdError: | ||||||
|                     response['status'] = True |                     response['status'] = True | ||||||
|                     response['text'] = ugettext('Terminated') |                     response['text'] = ugettext('Terminated') | ||||||
|  |                     vm_detail_obj = VMDetail.objects.filter( | ||||||
|  |                         vm_id=opennebula_vm_id).first() | ||||||
|  |                     vm_detail_obj.terminated_at = datetime.utcnow() | ||||||
|  |                     vm_detail_obj.save() | ||||||
|                     break |                     break | ||||||
|                 except BaseException: |                 except BaseException: | ||||||
|                     break |                     break | ||||||
|  |  | ||||||
|  | @ -1,4 +1,10 @@ | ||||||
| from hosting.models import UserHostingKey | import logging | ||||||
|  | from oca.pool import WrongIdError | ||||||
|  | 
 | ||||||
|  | from hosting.models import UserHostingKey, VMDetail | ||||||
|  | from opennebula_api.serializers import VirtualMachineSerializer | ||||||
|  | 
 | ||||||
|  | logger = logging.getLogger(__name__) | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| def get_all_public_keys(customer): | def get_all_public_keys(customer): | ||||||
|  | @ -9,3 +15,35 @@ def get_all_public_keys(customer): | ||||||
|     """ |     """ | ||||||
|     return UserHostingKey.objects.filter(user_id=customer.id).values_list( |     return UserHostingKey.objects.filter(user_id=customer.id).values_list( | ||||||
|         "public_key", flat=True) |         "public_key", flat=True) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def get_or_create_vm_detail(user, manager, vm_id): | ||||||
|  |     """ | ||||||
|  |     Returns VMDetail object related to given vm_id. Creates the object | ||||||
|  |      if it does not exist | ||||||
|  | 
 | ||||||
|  |     :param vm_id: The ID of the VM which should be greater than 0. | ||||||
|  |     :param user: The CustomUser object that owns this VM | ||||||
|  |     :param manager: The OpenNebulaManager object | ||||||
|  |     :return: The VMDetail object. None if vm_id is less than or equal to 0. | ||||||
|  |     Also, for the cases where the VMDetail does not exist and we can not | ||||||
|  |     fetch data about the VM from OpenNebula, the function returns None | ||||||
|  |     """ | ||||||
|  |     if vm_id <= 0: | ||||||
|  |         return None | ||||||
|  |     try: | ||||||
|  |         vm_detail_obj = VMDetail.objects.get(vm_id=vm_id) | ||||||
|  |     except VMDetail.DoesNotExist: | ||||||
|  |         try: | ||||||
|  |             vm_obj = manager.get_vm(vm_id) | ||||||
|  |         except (WrongIdError, ConnectionRefusedError) as e: | ||||||
|  |             logger.error(str(e)) | ||||||
|  |             return None | ||||||
|  |         vm = VirtualMachineSerializer(vm_obj).data | ||||||
|  |         vm_detail_obj = VMDetail.objects.create( | ||||||
|  |             user=user, vm_id=vm_id, disk_size=vm['disk_size'], | ||||||
|  |             cores=vm['cores'], memory=vm['memory'], | ||||||
|  |             configuration=vm['configuration'], ipv4=vm['ipv4'], | ||||||
|  |             ipv6=vm['ipv6'] | ||||||
|  |         ) | ||||||
|  |     return vm_detail_obj | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue