| 
									
										
										
										
											2017-08-21 00:41:46 +05:30
										 |  |  | import os | 
					
						
							| 
									
										
										
										
											2017-05-12 12:13:18 -05:00
										 |  |  | import logging | 
					
						
							| 
									
										
										
										
											2017-09-30 17:55:49 +05:30
										 |  |  | from dateutil.relativedelta import relativedelta | 
					
						
							| 
									
										
										
										
											2017-05-12 12:13:18 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-05-27 12:21:30 +02:00
										 |  |  | from django.db import models | 
					
						
							| 
									
										
										
										
											2017-09-30 18:05:02 +05:30
										 |  |  | from django.utils import timezone | 
					
						
							| 
									
										
										
										
											2016-05-03 00:59:40 -05:00
										 |  |  | from django.utils.functional import cached_property | 
					
						
							| 
									
										
										
										
											2017-08-21 00:41:46 +05:30
										 |  |  | from Crypto.PublicKey import RSA | 
					
						
							| 
									
										
										
										
											2017-05-03 23:19:32 -05:00
										 |  |  | from membership.models import StripeCustomer, CustomUser | 
					
						
							| 
									
										
										
										
											2017-08-17 18:16:36 +02:00
										 |  |  | from utils.models import BillingAddress | 
					
						
							| 
									
										
										
										
											2017-08-21 00:41:46 +05:30
										 |  |  | from utils.mixins import AssignPermissionsMixin | 
					
						
							| 
									
										
										
										
											2016-05-03 00:59:40 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-08 16:23:03 +05:30
										 |  |  | logger = logging.getLogger(__name__) | 
					
						
							| 
									
										
										
										
											2016-04-17 19:52:19 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-26 01:16:03 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-13 13:47:53 +02:00
										 |  |  | class HostingPlan(models.Model): | 
					
						
							|  |  |  |     disk_size = models.FloatField(default=0.0) | 
					
						
							|  |  |  |     cpu_cores = models.FloatField(default=0.0) | 
					
						
							|  |  |  |     memory = models.FloatField(default=0.0) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def serialize(self): | 
					
						
							|  |  |  |         return { | 
					
						
							|  |  |  |             'id': self.id, | 
					
						
							| 
									
										
										
										
											2017-06-29 17:34:40 +03:00
										 |  |  |             'cpu': self.cpu_cores, | 
					
						
							| 
									
										
										
										
											2017-05-13 13:47:53 +02:00
										 |  |  |             'memory': self.memory, | 
					
						
							|  |  |  |             'disk_size': self.disk_size, | 
					
						
							|  |  |  |             'price': self.price(), | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     @classmethod | 
					
						
							|  |  |  |     def get_serialized_configs(cls): | 
					
						
							|  |  |  |         return [cfg.serialize() | 
					
						
							|  |  |  |                 for cfg in cls.objects.all()] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def price(self): | 
					
						
							| 
									
										
										
										
											2017-05-14 02:17:48 +02:00
										 |  |  |         price = self.disk_size * 0.6 | 
					
						
							| 
									
										
										
										
											2017-05-13 13:47:53 +02:00
										 |  |  |         price += self.cpu_cores * 5 | 
					
						
							|  |  |  |         price += self.memory * 2 | 
					
						
							|  |  |  |         return price | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-29 17:34:40 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-07-10 22:08:51 -05:00
										 |  |  | class HostingOrder(AssignPermissionsMixin, models.Model): | 
					
						
							| 
									
										
										
										
											2016-05-03 00:59:40 -05:00
										 |  |  |     ORDER_APPROVED_STATUS = 'Approved' | 
					
						
							|  |  |  |     ORDER_DECLINED_STATUS = 'Declined' | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-12 12:07:05 +02:00
										 |  |  |     vm_id = models.IntegerField(default=0) | 
					
						
							| 
									
										
										
										
											2016-04-26 01:16:03 -05:00
										 |  |  |     customer = models.ForeignKey(StripeCustomer) | 
					
						
							|  |  |  |     billing_address = models.ForeignKey(BillingAddress) | 
					
						
							|  |  |  |     created_at = models.DateTimeField(auto_now_add=True) | 
					
						
							|  |  |  |     approved = models.BooleanField(default=False) | 
					
						
							| 
									
										
										
										
											2016-05-03 00:59:40 -05:00
										 |  |  |     last4 = models.CharField(max_length=4) | 
					
						
							|  |  |  |     cc_brand = models.CharField(max_length=10) | 
					
						
							| 
									
										
										
										
											2016-04-26 01:16:03 -05:00
										 |  |  |     stripe_charge_id = models.CharField(max_length=100, null=True) | 
					
						
							| 
									
										
										
										
											2017-05-12 12:13:18 -05:00
										 |  |  |     price = models.FloatField() | 
					
						
							| 
									
										
										
										
											2017-08-17 18:16:36 +02:00
										 |  |  |     subscription_id = models.CharField(max_length=100, null=True) | 
					
						
							| 
									
										
										
										
											2016-04-26 01:16:03 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-07-10 22:08:51 -05:00
										 |  |  |     permissions = ('view_hostingorder',) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     class Meta: | 
					
						
							|  |  |  |         permissions = ( | 
					
						
							|  |  |  |             ('view_hostingorder', 'View Hosting Order'), | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-14 02:12:42 -04:30
										 |  |  |     def __str__(self): | 
					
						
							|  |  |  |         return "%s" % (self.id) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-03 00:59:40 -05:00
										 |  |  |     @cached_property | 
					
						
							|  |  |  |     def status(self): | 
					
						
							|  |  |  |         return self.ORDER_APPROVED_STATUS if self.approved else self.ORDER_DECLINED_STATUS | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-26 01:16:03 -05:00
										 |  |  |     @classmethod | 
					
						
							| 
									
										
										
										
											2017-08-24 11:59:38 +05:30
										 |  |  |     def create(cls, price=None, vm_id=None, customer=None, | 
					
						
							|  |  |  |                billing_address=None): | 
					
						
							| 
									
										
										
										
											2017-05-12 12:13:18 -05:00
										 |  |  |         instance = cls.objects.create( | 
					
						
							|  |  |  |             price=price, | 
					
						
							|  |  |  |             vm_id=vm_id, | 
					
						
							|  |  |  |             customer=customer, | 
					
						
							|  |  |  |             billing_address=billing_address | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2016-07-10 22:08:51 -05:00
										 |  |  |         instance.assign_permissions(customer.user) | 
					
						
							| 
									
										
										
										
											2016-04-26 01:16:03 -05:00
										 |  |  |         return instance | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def set_approved(self): | 
					
						
							|  |  |  |         self.approved = True | 
					
						
							|  |  |  |         self.save() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def set_stripe_charge(self, stripe_charge): | 
					
						
							|  |  |  |         self.stripe_charge_id = stripe_charge.id | 
					
						
							| 
									
										
										
										
											2016-05-03 00:59:40 -05:00
										 |  |  |         self.last4 = stripe_charge.source.last4 | 
					
						
							|  |  |  |         self.cc_brand = stripe_charge.source.brand | 
					
						
							| 
									
										
										
										
											2016-04-26 01:16:03 -05:00
										 |  |  |         self.save() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-09-29 08:42:17 +02:00
										 |  |  |     def set_subscription_id(self, subscription_id, cc_details): | 
					
						
							| 
									
										
										
										
											2017-08-17 18:16:36 +02:00
										 |  |  |         """
 | 
					
						
							| 
									
										
										
										
											2017-08-24 11:59:38 +05:30
										 |  |  |         When creating a Stripe subscription, we have subscription id. | 
					
						
							|  |  |  |         We store this in the subscription_id field. | 
					
						
							| 
									
										
										
										
											2017-09-29 08:42:17 +02:00
										 |  |  |         This method sets the subscription id | 
					
						
							|  |  |  |         and the last4 and credit card brands used for this order. | 
					
						
							| 
									
										
										
										
											2017-08-17 18:16:36 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-09-29 08:42:17 +02:00
										 |  |  |         :param subscription_id: Stripe's subscription id | 
					
						
							| 
									
										
										
										
											2017-08-24 11:59:38 +05:30
										 |  |  |         :param cc_details: A dict containing card details | 
					
						
							|  |  |  |         {last4, brand} | 
					
						
							| 
									
										
										
										
											2017-08-17 18:16:36 +02:00
										 |  |  |         :return: | 
					
						
							|  |  |  |         """
 | 
					
						
							| 
									
										
										
										
											2017-09-29 08:42:17 +02:00
										 |  |  |         self.subscription_id = subscription_id | 
					
						
							| 
									
										
										
										
											2017-08-24 12:51:55 +05:30
										 |  |  |         self.last4 = cc_details.get('last4') | 
					
						
							|  |  |  |         self.cc_brand = cc_details.get('brand') | 
					
						
							| 
									
										
										
										
											2017-08-17 18:16:36 +02:00
										 |  |  |         self.save() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-11 00:11:33 -05:00
										 |  |  |     def get_cc_data(self): | 
					
						
							|  |  |  |         return { | 
					
						
							|  |  |  |             'last4': self.last4, | 
					
						
							|  |  |  |             'cc_brand': self.cc_brand, | 
					
						
							|  |  |  |         } if self.last4 and self.cc_brand else None | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-23 02:22:44 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-03 23:19:32 -05:00
										 |  |  | class UserHostingKey(models.Model): | 
					
						
							|  |  |  |     user = models.ForeignKey(CustomUser) | 
					
						
							|  |  |  |     public_key = models.TextField() | 
					
						
							| 
									
										
										
										
											2017-08-17 18:16:36 +02:00
										 |  |  |     private_key = models.FileField(upload_to='private_keys', blank=True) | 
					
						
							| 
									
										
										
										
											2017-05-03 23:19:32 -05:00
										 |  |  |     created_at = models.DateTimeField(auto_now_add=True) | 
					
						
							|  |  |  |     name = models.CharField(max_length=100) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     @staticmethod | 
					
						
							|  |  |  |     def generate_RSA(bits=2048): | 
					
						
							|  |  |  |         '''
 | 
					
						
							|  |  |  |         Generate an RSA keypair with an exponent of 65537 in PEM format | 
					
						
							|  |  |  |         param: bits The key length in bits | 
					
						
							|  |  |  |         Return private key and public key | 
					
						
							|  |  |  |         '''
 | 
					
						
							|  |  |  |         new_key = RSA.generate(2048, os.urandom) | 
					
						
							|  |  |  |         public_key = new_key.publickey().exportKey("OpenSSH") | 
					
						
							|  |  |  |         private_key = new_key.exportKey("PEM") | 
					
						
							|  |  |  |         return private_key, public_key | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     @classmethod | 
					
						
							|  |  |  |     def generate_keys(cls): | 
					
						
							|  |  |  |         private_key, public_key = cls.generate_RSA() | 
					
						
							|  |  |  |         # self.public_key = public_key | 
					
						
							|  |  |  |         # self.save(update_fields=['public_key']) | 
					
						
							|  |  |  |         return private_key, public_key | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-29 17:34:40 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-05 14:59:11 +02:00
										 |  |  | class HostingBill(AssignPermissionsMixin, models.Model): | 
					
						
							|  |  |  |     customer = models.ForeignKey(StripeCustomer) | 
					
						
							|  |  |  |     billing_address = models.ForeignKey(BillingAddress) | 
					
						
							| 
									
										
										
										
											2017-05-06 14:44:08 +02:00
										 |  |  |     total_price = models.FloatField(default=0.0) | 
					
						
							| 
									
										
										
										
											2017-05-05 14:59:11 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     permissions = ('view_hostingbill',) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     class Meta: | 
					
						
							|  |  |  |         permissions = ( | 
					
						
							|  |  |  |             ('view_hostingbill', 'View Hosting Bill'), | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def __str__(self): | 
					
						
							|  |  |  |         return "%s" % (self.customer.user.email) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-09 04:41:45 +02:00
										 |  |  |     @classmethod | 
					
						
							|  |  |  |     def create(cls, customer=None, billing_address=None): | 
					
						
							| 
									
										
										
										
											2017-08-24 11:59:38 +05:30
										 |  |  |         instance = cls.objects.create(customer=customer, | 
					
						
							|  |  |  |                                       billing_address=billing_address) | 
					
						
							| 
									
										
										
										
											2017-05-09 04:41:45 +02:00
										 |  |  |         return instance | 
					
						
							| 
									
										
										
										
											2017-09-25 00:00:45 +05:30
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 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) | 
					
						
							| 
									
										
										
										
											2017-09-30 17:55:49 +05:30
										 |  |  | 
 | 
					
						
							|  |  |  |     def end_date(self): | 
					
						
							| 
									
										
										
										
											2017-09-30 18:05:02 +05:30
										 |  |  |         end_date = self.terminated_at if self.terminated_at else timezone.now() | 
					
						
							| 
									
										
										
										
											2017-09-30 18:08:02 +05:30
										 |  |  |         months = relativedelta(end_date, self.created_at).months or 1 | 
					
						
							| 
									
										
										
										
											2017-09-30 18:10:34 +05:30
										 |  |  |         end_date = self.created_at + relativedelta(months=months, days=-1) | 
					
						
							| 
									
										
										
										
											2017-09-30 17:55:49 +05:30
										 |  |  |         return end_date |