API Integration

Please review carefully.
This commit is contained in:
Modulos 2017-05-12 12:07:05 +02:00
commit 130c00c8ee
19 changed files with 310 additions and 890 deletions

View file

@ -4,99 +4,8 @@ from django.core.urlresolvers import reverse
from utils.mailer import BaseEmail
from .forms import HostingOrderAdminForm
from .models import VirtualMachineType, VirtualMachinePlan, HostingOrder, \
ManageVM, HostingBill
from .opennebula_functions import HostingManageVMAdmin
from .models import HostingOrder, HostingBill
class HostingOrderAdmin(admin.ModelAdmin):
# fields = ('slug', 'imdb_link', 'start', 'finish', 'added_by')
list_display = ('id', 'created_at', 'plan', 'user')
search_fields = ['vm_plan__id', 'customer__user__email']
def save_model(self, request, obj, form, change):
if not change:
customer = form.cleaned_data.get('customer')
# Get and set billing address from the lastest charged order
last_order = HostingOrder.objects.filter(customer=customer).latest('id')
billing_address = last_order.billing_address
obj.billing_address = billing_address
charge = form.cleaned_data.get('charge')
# Associate an order with a stripe payment
obj.set_stripe_charge(charge)
# If the Stripe payment was successed, set order status approved
obj.set_approved()
# Assigning permissions
obj.assign_permissions(customer.user)
context = {
'order': obj,
'vm': obj.vm_plan,
'base_url': "{0}://{1}".format(request.scheme, request.get_host())
}
email_data = {
'subject': 'Your VM plan has been charged',
'to': obj.customer.user.email,
'context': context,
'template_name': 'vm_charged',
'template_path': 'hosting/emails/'
}
email = BaseEmail(**email_data)
email.send()
obj.save()
return obj
def get_form(self, request, obj=None, **kwargs):
if obj is None:
kwargs['form'] = HostingOrderAdminForm
return super(HostingOrderAdmin, self).get_form(request, obj, **kwargs)
def user(self, obj):
email = obj.customer.user.email
user_url = reverse("admin:membership_customuser_change", args=[obj.customer.user.id])
return format_html("<a href='{url}'>{email}</a>", url=user_url, email=email)
def plan(self, obj):
vm_name = obj.vm_plan.name
vm_url = reverse("admin:hosting_virtualmachineplan_change", args=[obj.vm_plan.id])
return format_html("<a href='{url}'>{vm_name}</a>", url=vm_url, vm_name=vm_name)
plan.short_description = "Virtual Machine Plan"
class VirtualMachinePlanAdmin(admin.ModelAdmin):
list_display = ('name', 'id', 'email')
def email(self, obj):
return obj.hosting_orders.latest('id').customer.user.email
def save_model(self, request, obj, form, change):
email = self.email(obj)
if 'status' in form.changed_data:
context = {
'vm': obj,
'base_url': "{0}://{1}".format(request.scheme, request.get_host())
}
email_data = {
'subject': 'Your VM has been activated',
'to': email,
'context': context,
'template_name': 'vm_status_changed',
'template_path': 'hosting/emails/'
}
email = BaseEmail(**email_data)
email.send()
obj.save()
admin.site.register(HostingOrder, HostingOrderAdmin)
admin.site.register(VirtualMachineType)
admin.site.register(VirtualMachinePlan, VirtualMachinePlanAdmin)
admin.site.register(ManageVM, HostingManageVMAdmin)
admin.site.register(HostingOrder)
admin.site.register(HostingBill)

View file

@ -7,39 +7,7 @@ from django.contrib.auth import authenticate
from utils.stripe_utils import StripeUtils
from .models import HostingOrder, VirtualMachinePlan, UserHostingKey
class HostingOrderAdminForm(forms.ModelForm):
class Meta:
model = HostingOrder
fields = ['vm_plan', 'customer']
def clean(self):
customer = self.cleaned_data.get('customer')
vm_plan = self.cleaned_data.get('vm_plan')
if vm_plan.status == VirtualMachinePlan.CANCELED_STATUS:
raise forms.ValidationError("""You can't make a charge over
a canceled virtual machine plan""")
if not customer:
raise forms.ValidationError("""You need select a costumer""")
# Make a charge to the customer
stripe_utils = StripeUtils()
charge_response = stripe_utils.make_charge(customer=customer.stripe_id,
amount=vm_plan.price)
charge = charge_response.get('response_object')
if not charge:
raise forms.ValidationError(charge_response.get('error'))
self.cleaned_data.update({
'charge': charge
})
return self.cleaned_data
from .models import HostingOrder, UserHostingKey
class HostingUserLoginForm(forms.Form):

View file

@ -0,0 +1,34 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.9.4 on 2017-05-12 10:06
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('hosting', '0037_merge'),
]
operations = [
migrations.RemoveField(
model_name='virtualmachineplan',
name='vm_type',
),
migrations.RemoveField(
model_name='hostingorder',
name='vm_plan',
),
migrations.AddField(
model_name='hostingorder',
name='vm_id',
field=models.IntegerField(default=0),
),
migrations.DeleteModel(
name='VirtualMachinePlan',
),
migrations.DeleteModel(
name='VirtualMachineType',
),
]

View file

@ -1,35 +1,20 @@
from django.shortcuts import redirect
from django.core.urlresolvers import reverse
from .models import VirtualMachinePlan, VirtualMachineType
class ProcessVMSelectionMixin(object):
def post(self, request, *args, **kwargs):
configuration = request.POST.get('configuration')
configuration_display = dict(VirtualMachinePlan.VM_CONFIGURATION).get(configuration)
vm_template = request.POST.get('vm_template')
vm_type = VirtualMachineType.objects.get(id=vm_template)
vm_specs = vm_type.get_specs()
#configuration = request.POST.get('configuration')
#configuration_display = dict(VirtualMachinePlan.VM_CONFIGURATION).get(configuration)
vm_template_id = request.POST.get('vm_template_id')
vm_specs.update({
'configuration_display': configuration_display,
'configuration': configuration,
'final_price': vm_type.final_price,
'vm_template': vm_template
'vm_template_id': vm_template_id
})
# vm_specs = {
# # 'cores': request.POST.get('cores'),
# # 'memory': request.POST.get('memory'),
# # 'disk_size': request.POST.get('disk_space'),
# # 'hosting_company': request.POST.get('hosting_company'),
# # 'location_code': request.POST.get('location_code'),
# # 'configuration': hosting,
# # 'configuration_detail': configuration_detail,
# 'final_price': request.POST.get('final_price')
# }
request.session['vm_specs'] = vm_specs
if not request.user.is_authenticated():
request.session['vm_specs'] = vm_specs
request.session['next'] = reverse('hosting:payment')
return redirect(reverse('hosting:login'))
return redirect(reverse('hosting:payment'))

View file

@ -22,224 +22,12 @@ from oca.pool import WrongNameError
import logging
logger = logging.getLogger(__name__)
class VirtualMachineType(models.Model):
description = models.TextField()
base_price = models.FloatField()
memory_price = models.FloatField()
core_price = models.FloatField()
disk_size_price = models.FloatField()
cores = models.IntegerField()
memory = models.IntegerField()
disk_size = models.IntegerField()
def __str__(self):
return "VM Type %s" % (self.id)
@cached_property
def final_price(self):
price = self.cores * self.core_price
price += self.memory * self.memory_price
price += self.disk_size * self.disk_size_price
return price
@classmethod
def get_serialized_vm_types(cls):
return [vm.get_serialized_data()
for vm in cls.objects.all()]
def calculate_price(self):
price = self.cores * self.core_price
price += self.memory * self.memory_price
price += self.disk_size * self.disk_size_price
# price += self.base_price
return price
# @classmethod
# def get_price(cls, vm_template):
# return cls.BASE_PRICE * vm_template
def get_specs(self):
return {
'memory': self.memory,
'cores': self.cores,
'disk_size': self.disk_size
}
# def calculate_price(self, vm_template):
# price = self.base_price * vm_template
# return price
# def defeault_price(self):
# price = self.base_price
# price += self.core_price
# price += self.memory_price
# price += self.disk_size_price * 10
# return price
def get_serialized_data(self):
return {
'description': self.description,
'core_price': self.core_price,
'disk_size_price': self.disk_size_price,
'memory_price': self.memory_price,
'id': self.id,
'final_price': self.final_price,
'cores': self.cores,
'memory': self.memory,
'disk_size': self.disk_size
}
class VirtualMachinePlan(AssignPermissionsMixin, models.Model):
PENDING_STATUS = 'pending'
ONLINE_STATUS = 'online'
CANCELED_STATUS = 'canceled'
VM_STATUS_CHOICES = (
(PENDING_STATUS, 'Pending for activation'),
(ONLINE_STATUS, 'Online'),
(CANCELED_STATUS, 'Canceled')
)
# DJANGO = 'django'
# RAILS = 'rails'
# NODEJS = 'nodejs'
# VM_CONFIGURATION = (
# (DJANGO, 'Ubuntu 14.04, Django'),
# (RAILS, 'Ubuntu 14.04, Rails'),
# (NODEJS, 'Debian, NodeJS'),
# )
VM_CONFIGURATION = (
('debian', 'Debian 8'),
('ubuntu', 'Ubuntu 16.06'),
('devuan', 'Devuan 1'),
('centos', 'CentOS 7')
)
permissions = ('view_virtualmachineplan',
'cancel_virtualmachineplan',
'change_virtualmachineplan')
cores = models.IntegerField()
memory = models.IntegerField()
disk_size = models.IntegerField()
vm_type = models.ForeignKey(VirtualMachineType, null=True)
price = models.FloatField()
public_key = models.TextField(blank=True)
status = models.CharField(max_length=20, choices=VM_STATUS_CHOICES, default=PENDING_STATUS)
ip = models.CharField(max_length=50, blank=True)
configuration = models.CharField(max_length=20, choices=VM_CONFIGURATION)
opennebula_id = models.IntegerField(null=True)
objects = VMPlansManager()
class Meta:
permissions = (
('view_virtualmachineplan', 'View Virtual Machine Plan'),
('cancel_virtualmachineplan', 'Cancel Virtual Machine Plan'),
)
def __str__(self):
return self.name
# @cached_property
# def hosting_company_name(self):
# return self.vm_type.get_hosting_company_display()
# @cached_property
# def location(self):
# return self.vm_type.get_location_display()
@cached_property
def name(self):
name = 'vm-%s' % self.id
return name
@cached_property
def notifications(self):
stripe_customer = StripeCustomer.objects.get(hostingorder__vm_plan=self)
backend = stored_messages_settings.STORAGE_BACKEND()
messages = backend.inbox_list(stripe_customer.user)
return messages
@classmethod
def create(cls, data, user):
instance = cls.objects.create(**data)
instance.assign_permissions(user)
return instance
def cancel_plan(self):
self.status = self.CANCELED_STATUS
self.save(update_fields=['status'])
@classmethod
def create_opennebula_vm(self, user, specs):
# Init opennebula manager using given user
opennebula_client = OpenNebulaManager(
user.email,
user.password[0:20],
create_user=True
)
# Create a vm in opennebula using given specs
vm = opennebula_client.create_vm(specs)
return vm
@classmethod
def get_vm(self, user, vm_id):
# Get opennebula client
opennebula_client = OpenNebulaManager(
email=user.email,
password=user.password[:20],
)
# Get vm given the id
vm = opennebula_client.get_vm(
user.email,
vm_id
)
# Parse vm data
vm_data = OpenNebulaManager.parse_vm(vm)
return vm_data
@classmethod
def get_vms(self, user):
# Get opennebula client
opennebula_client = OpenNebulaManager(
email=user.email,
password=user.password[:20],
)
# Get vm pool
vm_pool = opennebula_client.get_vms(user.email)
# Reset total price
self.total_price = 0
vms = []
# Add vm in vm_pool to context
for vm in vm_pool:
vm_data = OpenNebulaManager.parse_vm(vm)
vms.append(vm_data)
# self.total_price += price
# self.save()
return vms
class HostingOrder(AssignPermissionsMixin, models.Model):
ORDER_APPROVED_STATUS = 'Approved'
ORDER_DECLINED_STATUS = 'Declined'
vm_plan = models.ForeignKey(VirtualMachinePlan, related_name='hosting_orders')
vm_id = models.IntegerField(default=0)
customer = models.ForeignKey(StripeCustomer)
billing_address = models.ForeignKey(BillingAddress)
created_at = models.DateTimeField(auto_now_add=True)
@ -305,17 +93,6 @@ class UserHostingKey(models.Model):
# self.save(update_fields=['public_key'])
return private_key, public_key
class ManageVM(models.Model):
def has_add_permission(self, request):
return False
def has_delete_permission(self, request, obj=None):
return False
class Meta:
managed = False
class HostingBill(AssignPermissionsMixin, models.Model):
customer = models.ForeignKey(StripeCustomer)
billing_address = models.ForeignKey(BillingAddress)
@ -336,32 +113,3 @@ class HostingBill(AssignPermissionsMixin, models.Model):
instance = cls.objects.create(customer=customer, billing_address=billing_address)
return instance
def get_vms(self):
email = self.customer.user.email
# Get opennebula client
opennebula_client = OpenNebulaManager(create_user=False)
# Get vm pool
vm_pool = opennebula_client.get_vms(email)
# Reset total price
self.total_price = 0
vms = []
# Add vm in vm_pool to context
for vm in vm_pool:
vm_data = OpenNebulaManager.parse_vm(vm)
self.total_price += vm_data['price']
vms.append(vm_data)
self.save()
return vms
def get_user_opennebula_password():
'''
TODO: Implement the way we obtain the user's opennebula password
'''
pw = os.environ.get('OPENNEBULA_USER_PW')
if pw is None:
raise Exception("Define OPENNEBULA_USER_PW env variable")
return pw

View file

@ -78,7 +78,7 @@
</div>
<div class="row">
<div class="col-sm-6">
{% trans "CH02 ............" %}
{% trans "CH02 0900 0000 6071 8848 8%}
</div>
<div class="col-sm-6">
{% trans "POFICHBEXXX" %}

View file

@ -12,10 +12,14 @@
{% csrf_token %}
<div class="form-group">
Select VM:
<select name="vm_template">
{% for vm in vm_types %}
<select name="vm_template_id">
{% for template in templates %}
<option value="{{vm.id}}">CORE: {{vm.cores}}, RAM: {{vm.memory}}, SSD: {{vm.disk_size}} </option>
<option value="{{template.id}}">
CORE: {{template.cores}},
RAM: {{template.memory}},r
SSD: {{template.disk_size}}
</option>
{% endfor %}
</select>
@ -42,4 +46,4 @@
</div>
{%endblock%}
{%endblock%}

View file

@ -49,17 +49,13 @@
<h3><b>{% trans "Order summary"%}</b></h3>
<hr>
<div class="content">
<p><b>{% trans "Type"%}</b> <span class="pull-right">{{order.vm_plan.hosting_company_name}}</span></p>
<p><b>{% trans "Cores"%}</b> <span class="pull-right">{{vm.cores}}</span></p>
<hr>
<p><b>{% trans "Configuration"%}</b> <span class="pull-right">{{order.vm_plan.get_configuration_display}}</span></p>
<p><b>{% trans "Memory"%}</b> <span class="pull-right">{{vm.memory}} GiB</span></p>
<hr>
<p><b>{% trans "Cores"%}</b> <span class="pull-right">{{order.vm_plan.cores}}</span></p>
<p><b>{% trans "Disk space"%}</b> <span class="pull-right">{{vm.disk_size}} GiB</span></p>
<hr>
<p><b>{% trans "Memory"%}</b> <span class="pull-right">{{order.vm_plan.memory}} GiB</span></p>
<hr>
<p><b>{% trans "Disk space"%}</b> <span class="pull-right">{{order.vm_plan.disk_size}} GiB</span></p>
<hr>
<h4>{% trans "Total"%}<p class="pull-right"><b>{{order.vm_plan.price}} CHF</b></p></h4>
<h4>{% trans "Total"%}<p class="pull-right"><b>{{vm.price}} CHF</b></p></h4>
</div>
<br/>
{% url 'hosting:payment' as payment_url %}

View file

@ -88,15 +88,14 @@
<div class="content">
<!-- <p><b>Type</b> <span class="pull-right">{{request.session.vm_specs.location_code}}</span></p> -->
<!-- <hr> -->
<p><b>Cores</b> <span class="pull-right">{{request.session.vm_specs.cores}}</span></p>
<p><b>Cores</b> <span class="pull-right">{{request.session.template.cores}}</span></p>
<hr>
<p><b>Configuration</b> <span class="pull-right">{{request.session.vm_specs.configuration_display}}</span></p>
<hr>
<p><b>Memory</b> <span class="pull-right">{{request.session.vm_specs.memory}} GiB</span></p>
<p><b>Memory</b> <span class="pull-right">{{request.session.template.memory}} GiB</span></p>
<hr>
<p><b>Disk space</b> <span class="pull-right">{{request.session.vm_specs.disk_size}} GiB</span></p>
<p><b>Disk space</b> <span class="pull-right">{{request.session.template.disk_size}} GiB</span></p>
<hr>
<h4>Total<p class="pull-right"><b>{{request.session.vm_specs.final_price}} CHF</b></p></h4>
<h4>Total<p
class="pull-right"><b>{{request.session.template.price }} CHF</b></p></h4>
</div>
</div>
</div>

View file

@ -25,12 +25,6 @@
{% trans "Billing"%}
</a>
</li>
<li>
<a href="#orders-v" data-toggle="tab">
<i class="fa fa-credit-card"></i>
{% trans "Orders"%}
</a>
</li>
<li>
<a href="#status-v" data-toggle="tab">
<i class="fa fa-signal" aria-hidden="true"></i> {% trans "Status"%}
@ -109,54 +103,20 @@
</div>
</div>
</div>
<div class="tab-pane" id="orders-v">
<div class="row">
<div class="col-md-12">
<table class="table borderless table-hover">
<h3>Orders</h3>
<br/>
<thead>
<tr>
<th>#</th>
<th>{% trans "Date"%}</th>
<th>{% trans "Amount"%}</th>
<th>{% trans "Status"%}</th>
<th></th>
</tr>
</thead>
<tbody>
{% for order in virtual_machine.hosting_orders.all %}
<tr>
<td scope="row">{{order.id}}</td>
<td>{{order.created_at}}</td>
<td>{{order.vm_plan.price}} CHF</td>
<td>{% if order.approved %}
<span class="text-success strong">{% trans "Approved"%}</span>
{% else%}
<span class="text-danger strong">{% trans "Declined"%}</span>
{% endif%}
</td>
<td>
<button type="button" class="btn btn-default"><a href="{% url 'hosting:orders' order.id %}">{% trans "View Detail"%}</a></button>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div><!--/col-12-->
</div><!--/row-->
</div>
<div class="tab-pane" id="status-v">
<div class="row ">
<div class="col-md-12 inline-headers">
<h3>{% trans "Current status"%}</h3>
<div class="pull-right space-above">
{% if virtual_machine.status == 'pending' %}
<span class="label label-warning"><strong>{{virtual_machine.get_status_display}}</strong></span>
{% elif virtual_machine.status == 'online' %}
<span class="label label-success"><strong>{{virtual_machine.get_status_display}}</strong></span>
{% elif virtual_machine.status == 'canceled'%}
<span class="label label-danger"><strong>{{virtual_machine.get_status_display}}</strong></span>
{% if virtual_machine.state == 'PENDING' %}
<span class="label
label-warning"><strong>Pending</strong></span>
{% elif virtual_machine.state == 'ACTIVE' %}
<span class="label
label-success"><strong>Online</strong></span>
{% elif virtual_machine.state == 'FAILED'%}
<span class="label
label-danger"><strong>Failed</strong></span>
{% endif %}
</div>
</div>
@ -165,11 +125,13 @@
<div class="row">
<div class="col-md-12 space-above-big">
<div class="pull-right">
<form method="POST" id="virtual_machine_cancel_form" class="cancel-form" action="{% url 'hosting:virtual_machines' virtual_machine.id %}">
<form method="POST"
id="virtual_machine_cancel_form" class="cancel-form" action="{% url 'hosting:virtual_machines' virtual_machine.vm_id %}">
{% csrf_token %}
</form>
<button type="text" data-href="{% url 'hosting:virtual_machines' virtual_machine.id %}" data-toggle="modal" data-target="#confirm-cancel" class="btn btn-danger">{% trans "Cancel Virtual Machine"%}</button>
<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 "Cancel Virtual Machine"%}</button>
</div>
</div>
@ -181,7 +143,7 @@
{% trans "Cancel your Virtual Machine"%}
</div>
<div class="modal-body">
{% trans "Are you sure do you want to cancel your Virtual Machine "%} {{vm.virtual_machine}} {% trans "plan?"%}
{% trans "Are you sure do you want to cancel your Virtual Machine "%} {{virtual_machine.name}} {% trans "plan?"%}
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">{% trans "Cancel"%}</button>
@ -207,12 +169,3 @@
</div>
{%endblock%}

View file

@ -20,9 +20,9 @@
</tr>
</thead>
<tbody>
{% for vm in vms_opennebula %}
{% for vm in vms %}
<tr>
<td scope="row">{{vm.deploy_id}}</td>
<td scope="row">{{vm.vm_id}}</td>
<td>{{vm.price}} CHF</td>
<td>
@ -36,7 +36,8 @@
</td>
<td>
<button type="button" class="btn btn-default"><a href="{% url 'hosting:virtual_machines' vm.id %}">{% trans "View Detail"%}</a></button>
<button type="button" class="btn btn-default"><a
href="{% url 'hosting:virtual_machines' vm.vm_id %}">{% trans "View Detail"%}</a></button>
</td>
</tr>
{% endfor %}
@ -66,4 +67,4 @@
</div>
{%endblock%}
{%endblock%}

View file

@ -19,16 +19,18 @@ from stored_messages.models import Message
from stored_messages.api import mark_read
from membership.models import CustomUser, StripeCustomer
from utils.stripe_utils import StripeUtils
from utils.forms import BillingAddressForm, PasswordResetRequestForm
from utils.views import PasswordResetViewMixin, PasswordResetConfirmViewMixin, LoginViewMixin
from utils.mailer import BaseEmail
from .models import VirtualMachineType, VirtualMachinePlan, HostingOrder, HostingBill, UserHostingKey
from .models import HostingOrder, HostingBill, UserHostingKey
from .forms import HostingUserSignupForm, HostingUserLoginForm, UserHostingKeyForm
from .mixins import ProcessVMSelectionMixin
from .opennebula_functions import HostingManageVMAdmin, OpenNebulaManager
from opennebula_api.models import OpenNebulaManager
from opennebula_api.serializers import VirtualMachineSerializer,\
VirtualMachineTemplateSerializer
from oca.exceptions import OpenNebulaException
from oca.pool import WrongNameError
@ -282,48 +284,26 @@ class PaymentVMView(LoginRequiredMixin, FormView):
if form.is_valid():
context = self.get_context_data()
specifications = request.session.get('vm_specs')
specifications = request.session.get('template')
vm_template = specifications.get('vm_template', 1)
vm_type = VirtualMachineType.objects.get(id=vm_template)
specs = vm_type.get_specs()
final_price = vm_type.calculate_price()
plan_data = {
'vm_type': vm_type,
'configuration': specifications.get(
'configuration',
'django'
),
'price': final_price
}
plan_data.update(specs)
vm_template_id = specifications.get('id', 1)
final_price = specifications.get('price', 1)
token = form.cleaned_data.get('token')
owner = self.request.user
# Get or create stripe customer
customer = StripeCustomer.get_or_create(email=self.request.user.email,
customer = StripeCustomer.get_or_create(email=owner.email,
token=token)
if not customer:
form.add_error("__all__", "Invalid credit card")
return self.render_to_response(self.get_context_data(form=form))
# Create Virtual Machine Plan
plan = VirtualMachinePlan.create(plan_data, request.user)
# Create Billing Address
billing_address = form.save()
# Create a Hosting Order
order = HostingOrder.create(vm_plan=plan, customer=customer,
billing_address=billing_address)
# Create a Hosting Bill
bill = HostingBill.create(customer=customer, billing_address=billing_address)
# Make stripe charge to a customer
stripe_utils = StripeUtils()
charge_response = stripe_utils.make_charge(amount=final_price,
@ -340,24 +320,34 @@ class PaymentVMView(LoginRequiredMixin, FormView):
charge = charge_response.get('response_object')
# Create OpenNebulaManager
manager = OpenNebulaManager(email=owner.email,
password=owner.password[0:20],
create_user=True)
template = manager.get_template(vm_template_id)
# Create a vm using logged user
vm_id = manager.create_vm(vm_template_id)
# Create a Hosting Order
order = HostingOrder.create(vm_id=vm_id, customer=customer,
billing_address=billing_address)
# Create a Hosting Bill
bill = HostingBill.create(customer=customer, billing_address=billing_address)
# Associate an order with a stripe payment
order.set_stripe_charge(charge)
# If the Stripe payment was successed, set order status approved
order.set_approved()
# Create a vm using logged user
oppennebula_vm_id = VirtualMachinePlan.create_opennebula_vm(
self.request.user,
specs
)
vm = VirtualMachineSerializer(manager.get_vm(vm_id)).data
plan.oppenebula_id = oppennebula_vm_id
plan.save()
# Send notification to ungleich as soon as VM has been booked
context = {
'vm': plan,
'vm': vm,
'order': order,
'base_url': "{0}://{1}".format(request.scheme, request.get_host())
@ -384,6 +374,18 @@ class OrdersHostingDetailView(PermissionRequiredMixin, LoginRequiredMixin, Detai
permission_required = ['view_hostingorder']
model = HostingOrder
def get_context_data(self, **kwargs):
# Get context
context = super(DetailView, self).get_context_data(**kwargs)
obj = self.get_object()
owner = self.request.user
manager = OpenNebulaManager(email=owner.email,
password=owner.password[0:20],
create_user=True)
vm = manager.get_vm(obj.vm_id)
context['vm'] = VirtualMachineSerializer(vm).data
class OrdersHostingListView(LoginRequiredMixin, ListView):
template_name = "hosting/orders.html"
login_url = reverse_lazy('hosting:login')
@ -408,24 +410,17 @@ class VirtualMachinesPlanListView(LoginRequiredMixin, ListView):
template_name = "hosting/virtual_machines.html"
login_url = reverse_lazy('hosting:login')
context_object_name = "vms"
model = VirtualMachinePlan
paginate_by = 10
ordering = '-id'
def get_context_data(self, **kwargs):
context = super(VirtualMachinesPlanListView, self).get_context_data(**kwargs)
context.update({
'vms_opennebula': VirtualMachinePlan.get_vms(self.request.user)
})
return context
def get_queryset(self):
# hosting_admin = HostingManageVMAdmin.__new__(HostingManageVMAdmin)
# print(hosting_admin.show_vms_view(self.request))
# print(VirtualMachinePlan.get_vms(self.request.user.))
user = self.request.user
self.queryset = VirtualMachinePlan.objects.active(user)
return super(VirtualMachinesPlanListView, self).get_queryset()
owner = self.request.user
manager = OpenNebulaManager(email=owner.email,
password=owner.password[0:20],
create_user=True)
queryset = manager.get_vms()
serializer = VirtualMachineSerializer(queryset, many=True)
return serializer.data
class CreateVirtualMachinesView(LoginRequiredMixin, View):
@ -433,92 +428,56 @@ class CreateVirtualMachinesView(LoginRequiredMixin, View):
login_url = reverse_lazy('hosting:login')
def get(self, request, *args, **kwargs):
#TODO: Replace with OpenNebulaManager.get_apps
templates = OpenNebulaManager().get_templates()
data = VirtualMachineTemplateSerializer(templates, many=True).data
context = {
'vm_types': VirtualMachineType.get_serialized_vm_types(),
'configuration_options': VirtualMachinePlan.VM_CONFIGURATION
'templates': data,
#'configuration_options': VirtualMachinePlan.VM_CONFIGURATION
}
# context = {}
return render(request, self.template_name, context)
def post(self, request):
configuration = request.POST.get('configuration')
configuration_display = dict(VirtualMachinePlan.VM_CONFIGURATION).get(configuration)
vm_template = request.POST.get('vm_template')
vm_type = VirtualMachineType.objects.get(id=vm_template)
vm_specs = vm_type.get_specs()
vm_specs.update({
'configuration_display': configuration_display,
'configuration': configuration,
'final_price': vm_type.final_price,
'vm_template': vm_template
})
request.session['vm_specs'] = vm_specs
#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 = OpenNebulaManager().get_template(template_id)
data = VirtualMachineTemplateSerializer(template).data
vm_specs = {
#'configuration_display': configuration_display,
#'configuration': configuration,
'template': data,
}
request.session['template'] = data
return redirect(reverse('hosting:payment'))
# def get_queryset(self):
# # hosting_admin = HostingManageVMAdmin.__new__(HostingManageVMAdmin)
# # print(hosting_admin.show_vms(self.request))
# user = self.request.user
# self.queryset = VirtualMachinePlan.objects.active(user)
# return super(VirtualMachinesPlanListView, self).get_queryset()
class VirtualMachineView(PermissionRequiredMixin, LoginRequiredMixin, View):
class VirtualMachineView(LoginRequiredMixin, View):
template_name = "hosting/virtual_machine_detail.html"
login_url = reverse_lazy('hosting:login')
# model = VirtualMachinePlan
# context_object_name = "virtual_machine"
permission_required = ['view_virtualmachineplan', 'cancel_virtualmachineplan']
# fields = '__all__'
# def get_context_data(self, **kwargs):
# vm_plan = get_object()
# context = super(VirtualMachineView, self).get_context_data(**kwargs)
# context.update({
# 'opennebula_vm': VirtualMachinePlan.get_vm(
# self.request.user.email,
# opennebula_id
# )
# })
# return context
# def get_object(self, queryset=None):
# # if queryset is None:
# # queryset = self.get_queryset()
# # Next, try looking up by primary key.
# vm_id = self.kwargs.get(self.pk_url_kwarg)
# try:
# return VirtualMachinePlan.get_vm(
# self.request.user.email,
# vm_id
# )
# except Exception as error:
# raise Http404()
# def get_success_url(self):
# vm = self.get_object()
# final_url = "%s%s" % (reverse('hosting:virtual_machines', kwargs={'pk': vm.id}),
# '#status-v')
# return final_url
def get(self, request, *args, **kwargs):
owner = self.request.user
manager = OpenNebulaManager(email=owner.email,
password=owner.password[0:20],
create_user=True)
vm_id = self.kwargs.get('pk')
try:
opennebula_vm = VirtualMachinePlan.get_vm(
self.request.user,
vm_id
)
vm = manager.get_vm(vm_id)
serializer = VirtualMachineSerializer(vm)
except Exception as error:
print(error)
raise Http404()
context = {
'virtual_machine': opennebula_vm,
'virtual_machine': serializer.data,
}
# context = {}
return render(request, self.template_name, context)
def post(self, *args, **kwargs):
#TODO: add api to OpenNebulaManager
vm = self.get_object()
vm.cancel_plan()
@ -564,10 +523,14 @@ class HostingBillDetailView(PermissionRequiredMixin, LoginRequiredMixin, DetailV
def get_context_data(self, **kwargs):
# Get context
context = super(DetailView, self).get_context_data(**kwargs)
owner = self.request.user
manager = OpenNebulaManager(email=owner.email,
password=owner.password[0:20],
create_user=True)
# Get vms
try:
context['vms'] = self.get_object().get_vms()
except:
pass
queryset = manager.get_vms()
vms = VirtualMachineSerializer(queryset, many=True).data
context['vms'] = vms
return context