Added datacenterlight/tasks.py
This commit is contained in:
		
					parent
					
						
							
								26b4feb1d1
							
						
					
				
			
			
				commit
				
					
						f950c1defb
					
				
			
		
					 1 changed files with 162 additions and 0 deletions
				
			
		
							
								
								
									
										162
									
								
								datacenterlight/tasks.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										162
									
								
								datacenterlight/tasks.py
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,162 @@ | ||||||
|  | from __future__ import absolute_import, unicode_literals | ||||||
|  | from dynamicweb.celery import app | ||||||
|  | from celery.utils.log import get_task_logger | ||||||
|  | from django.conf import settings | ||||||
|  | from opennebula_api.models import OpenNebulaManager | ||||||
|  | from opennebula_api.serializers import VirtualMachineSerializer | ||||||
|  | from hosting.models import HostingOrder, HostingBill | ||||||
|  | from utils.forms import UserBillingAddressForm | ||||||
|  | from datetime import datetime | ||||||
|  | from membership.models import StripeCustomer | ||||||
|  | from django.core.mail import EmailMessage | ||||||
|  | from utils.models import BillingAddress | ||||||
|  | 
 | ||||||
|  | logger = get_task_logger(__name__) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def retry_task(task, exception=None): | ||||||
|  |     """Retries the specified task using a "backing off countdown", | ||||||
|  |     meaning that the interval between retries grows exponentially | ||||||
|  |     with every retry. | ||||||
|  | 
 | ||||||
|  |     Arguments: | ||||||
|  |         task: | ||||||
|  |             The task to retry. | ||||||
|  | 
 | ||||||
|  |         exception: | ||||||
|  |             Optionally, the exception that caused the retry. | ||||||
|  |     """ | ||||||
|  | 
 | ||||||
|  |     def backoff(attempts): | ||||||
|  |         return 2 ** attempts | ||||||
|  | 
 | ||||||
|  |     kwargs = { | ||||||
|  |         'countdown': backoff(task.request.retries), | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     if exception: | ||||||
|  |         kwargs['exc'] = exception | ||||||
|  | 
 | ||||||
|  |     if task.request.retries > settings.CELERY_MAX_RETRIES: | ||||||
|  |         msg_text = 'Finished {} retries for create_vm_task'.format(task.request.retries) | ||||||
|  |         logger.log(msg_text) | ||||||
|  |         # Try sending email and stop | ||||||
|  |         email_data = { | ||||||
|  |             'subject': '{} CELERY TASK ERROR: {}'.format(settings.DCL_TEXT, msg_text), | ||||||
|  |             'from_email': settings.DCL_SUPPORT_FROM_ADDRESS, | ||||||
|  |             'to': ['info@ungleich.ch'], | ||||||
|  |             'body': "\n".join(["%s=%s" % (k, v) for (k, v) in kwargs.items()]), | ||||||
|  |         } | ||||||
|  |         email = EmailMessage(**email_data) | ||||||
|  |         email.send() | ||||||
|  |         return | ||||||
|  |     else: | ||||||
|  |         raise task.retry(**kwargs) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | @app.task(bind=True) | ||||||
|  | def create_vm_task(self, vm_template_id, user, specs, template, stripe_customer_id, billing_address_data, | ||||||
|  |                    billing_address_id, | ||||||
|  |                    charge): | ||||||
|  |     try: | ||||||
|  |         final_price = specs.get('price') | ||||||
|  |         billing_address = BillingAddress.objects.filter(id=billing_address_id).first() | ||||||
|  |         customer = StripeCustomer.objects.filter(id=stripe_customer_id).first() | ||||||
|  |         # Create OpenNebulaManager | ||||||
|  |         manager = OpenNebulaManager(email=settings.OPENNEBULA_USERNAME, | ||||||
|  |                                     password=settings.OPENNEBULA_PASSWORD) | ||||||
|  | 
 | ||||||
|  |         # Create a vm using oneadmin, also specify the name | ||||||
|  |         vm_id = manager.create_vm( | ||||||
|  |             template_id=vm_template_id, | ||||||
|  |             specs=specs, | ||||||
|  |             vm_name="{email}-{template_name}-{date}".format( | ||||||
|  |                 email=user.get('email'), | ||||||
|  |                 template_name=template.get('name'), | ||||||
|  |                 date=int(datetime.now().strftime("%s"))) | ||||||
|  |         ) | ||||||
|  | 
 | ||||||
|  |         # Create a Hosting Order | ||||||
|  |         order = HostingOrder.create( | ||||||
|  |             price=final_price, | ||||||
|  |             vm_id=vm_id, | ||||||
|  |             customer=customer, | ||||||
|  |             billing_address=billing_address | ||||||
|  |         ) | ||||||
|  | 
 | ||||||
|  |         # Create a Hosting 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 | ||||||
|  |         charge_object = DictDotLookup(charge) | ||||||
|  |         order.set_stripe_charge(charge_object) | ||||||
|  | 
 | ||||||
|  |         # If the Stripe payment succeeds, set order status approved | ||||||
|  |         order.set_approved() | ||||||
|  | 
 | ||||||
|  |         vm = VirtualMachineSerializer(manager.get_vm(vm_id)).data | ||||||
|  | 
 | ||||||
|  |         context = { | ||||||
|  |             'name': user.get('name'), | ||||||
|  |             'email': user.get('email'), | ||||||
|  |             'cores': specs.get('cpu'), | ||||||
|  |             'memory': specs.get('memory'), | ||||||
|  |             'storage': specs.get('disk_size'), | ||||||
|  |             'price': specs.get('price'), | ||||||
|  |             'template': template.get('name'), | ||||||
|  |             'vm.name': vm['name'], | ||||||
|  |             'vm.id': vm['vm_id'], | ||||||
|  |             'order.id': order.id | ||||||
|  |         } | ||||||
|  |         email_data = { | ||||||
|  |             'subject': settings.DCL_TEXT + " Order from %s" % context['email'], | ||||||
|  |             'from_email': settings.DCL_SUPPORT_FROM_ADDRESS, | ||||||
|  |             'to': ['info@ungleich.ch'], | ||||||
|  |             'body': "\n".join(["%s=%s" % (k, v) for (k, v) in context.items()]), | ||||||
|  |             'reply_to': [context['email']], | ||||||
|  |         } | ||||||
|  |         email = EmailMessage(**email_data) | ||||||
|  |         email.send() | ||||||
|  |     except Exception as e: | ||||||
|  |         logger.error(str(e)) | ||||||
|  |         retry_task(self) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | class DictDotLookup(object): | ||||||
|  |     """ | ||||||
|  |     Creates objects that behave much like a dictionaries, but allow nested | ||||||
|  |     key access using object '.' (dot) lookups. | ||||||
|  |     """ | ||||||
|  | 
 | ||||||
|  |     def __init__(self, d): | ||||||
|  |         for k in d: | ||||||
|  |             if isinstance(d[k], dict): | ||||||
|  |                 self.__dict__[k] = DictDotLookup(d[k]) | ||||||
|  |             elif isinstance(d[k], (list, tuple)): | ||||||
|  |                 l = [] | ||||||
|  |                 for v in d[k]: | ||||||
|  |                     if isinstance(v, dict): | ||||||
|  |                         l.append(DictDotLookup(v)) | ||||||
|  |                     else: | ||||||
|  |                         l.append(v) | ||||||
|  |                 self.__dict__[k] = l | ||||||
|  |             else: | ||||||
|  |                 self.__dict__[k] = d[k] | ||||||
|  | 
 | ||||||
|  |     def __getitem__(self, name): | ||||||
|  |         if name in self.__dict__: | ||||||
|  |             return self.__dict__[name] | ||||||
|  | 
 | ||||||
|  |     def __iter__(self): | ||||||
|  |         return iter(self.__dict__.keys()) | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue