dynamicweb/hosting/models.py

175 lines
5.4 KiB
Python

import os
import logging
from django.db import models
from django.utils.functional import cached_property
from Crypto.PublicKey import RSA
from membership.models import StripeCustomer, CustomUser
from utils.models import BillingAddress
from utils.mixins import AssignPermissionsMixin
logger = logging.getLogger(__name__)
class HostingPlan(models.Model):
disk_size = models.FloatField(default=0.0)
cpu_cores = models.FloatField(default=0.0)
memory = models.FloatField(default=0.0)
def serialize(self):
return {
'id': self.id,
'cpu': self.cpu_cores,
'memory': self.memory,
'disk_size': self.disk_size,
'price': self.price(),
}
@classmethod
def get_serialized_configs(cls):
return [cfg.serialize()
for cfg in cls.objects.all()]
def price(self):
price = self.disk_size * 0.6
price += self.cpu_cores * 5
price += self.memory * 2
return price
class HostingOrder(AssignPermissionsMixin, models.Model):
ORDER_APPROVED_STATUS = 'Approved'
ORDER_DECLINED_STATUS = 'Declined'
vm_id = models.IntegerField(default=0)
customer = models.ForeignKey(StripeCustomer)
billing_address = models.ForeignKey(BillingAddress)
created_at = models.DateTimeField(auto_now_add=True)
approved = models.BooleanField(default=False)
last4 = models.CharField(max_length=4)
cc_brand = models.CharField(max_length=10)
stripe_charge_id = models.CharField(max_length=100, null=True)
price = models.FloatField()
subscription_id = models.CharField(max_length=100, null=True)
permissions = ('view_hostingorder',)
class Meta:
permissions = (
('view_hostingorder', 'View Hosting Order'),
)
def __str__(self):
return "%s" % (self.id)
@cached_property
def status(self):
return self.ORDER_APPROVED_STATUS if self.approved else self.ORDER_DECLINED_STATUS
@classmethod
def create(cls, price=None, vm_id=None, customer=None,
billing_address=None):
instance = cls.objects.create(
price=price,
vm_id=vm_id,
customer=customer,
billing_address=billing_address
)
instance.assign_permissions(customer.user)
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
self.last4 = stripe_charge.source.last4
self.cc_brand = stripe_charge.source.brand
self.save()
def set_subscription_id(self, subscription_id, cc_details):
"""
When creating a Stripe subscription, we have subscription id.
We store this in the subscription_id field.
This method sets the subscription id
and the last4 and credit card brands used for this order.
:param subscription_id: Stripe's subscription id
:param cc_details: A dict containing card details
{last4, brand}
:return:
"""
self.subscription_id = subscription_id
self.last4 = cc_details.get('last4')
self.cc_brand = cc_details.get('brand')
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):
user = models.ForeignKey(CustomUser)
public_key = models.TextField()
private_key = models.FileField(upload_to='private_keys', blank=True)
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
class HostingBill(AssignPermissionsMixin, models.Model):
customer = models.ForeignKey(StripeCustomer)
billing_address = models.ForeignKey(BillingAddress)
total_price = models.FloatField(default=0.0)
permissions = ('view_hostingbill',)
class Meta:
permissions = (
('view_hostingbill', 'View Hosting Bill'),
)
def __str__(self):
return "%s" % (self.customer.user.email)
@classmethod
def create(cls, customer=None, billing_address=None):
instance = cls.objects.create(customer=customer,
billing_address=billing_address)
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)