Add images as configuration

This commit is contained in:
Modulos 2017-05-13 06:59:57 +02:00
parent c816d280ee
commit 75d93b2aad
6 changed files with 108 additions and 46 deletions

View file

@ -7,7 +7,6 @@ import oca
from django.db import models from django.db import models
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from django.utils.functional import cached_property from django.utils.functional import cached_property
from hosting.opennebula_functions import OpenNebulaManager
from django.conf import settings from django.conf import settings
@ -18,8 +17,6 @@ from membership.models import StripeCustomer, CustomUser
from utils.models import BillingAddress from utils.models import BillingAddress
from utils.mixins import AssignPermissionsMixin from utils.mixins import AssignPermissionsMixin
from .managers import VMPlansManager from .managers import VMPlansManager
from oca.exceptions import OpenNebulaException
from oca.pool import WrongNameError
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)

View file

@ -24,16 +24,16 @@
{% endfor %} {% endfor %}
</select> </select>
</div> </div>
<!-- <div class="form-group"> <div class="form-group">
Select VM Configuration: Select VM Configuration:
<select name="configuration"> <select name="vm_image_id">
{% for config in configuration_options %} {% for image in images %}
<option value="{{config.0}}">{{config.1}} </option> <option value="{{image.id}}">{{image.name}} </option>
{% endfor %} {% endfor %}
</select> </select>
</div> --> </div>
<div class="form-group"> <div class="form-group">
<button class="btn btn-success" >{% trans "Start VM"%} </button> <button class="btn btn-success" >{% trans "Start VM"%} </button>
</div> </div>

View file

@ -31,7 +31,9 @@ from .mixins import ProcessVMSelectionMixin
from opennebula_api.models import OpenNebulaManager from opennebula_api.models import OpenNebulaManager
from opennebula_api.serializers import VirtualMachineSerializer,\ from opennebula_api.serializers import VirtualMachineSerializer,\
VirtualMachineTemplateSerializer VirtualMachineTemplateSerializer,\
ImageSerializer
from oca.exceptions import OpenNebulaException from oca.exceptions import OpenNebulaException
from oca.pool import WrongNameError from oca.pool import WrongNameError
@ -392,6 +394,7 @@ class PaymentVMView(LoginRequiredMixin, FormView):
specifications = request.session.get('template') specifications = request.session.get('template')
vm_template_id = specifications.get('id', 1) vm_template_id = specifications.get('id', 1)
vm_image_id = request.session.get('image').get('id', 1)
final_price = specifications.get('price', 1) final_price = specifications.get('price', 1)
@ -428,8 +431,6 @@ class PaymentVMView(LoginRequiredMixin, FormView):
# Create OpenNebulaManager # Create OpenNebulaManager
manager = OpenNebulaManager(email=owner.email, manager = OpenNebulaManager(email=owner.email,
password=owner.password) password=owner.password)
template = manager.get_template(vm_template_id)
# Get user ssh key # Get user ssh key
try: try:
user_key = UserHostingKey.objects.get( user_key = UserHostingKey.objects.get(
@ -441,8 +442,9 @@ class PaymentVMView(LoginRequiredMixin, FormView):
# Create a vm using logged user # Create a vm using logged user
vm_id = manager.create_vm( vm_id = manager.create_vm(
vm_template_id, template_id=vm_template_id,
ssh_key=user_key.public_key ssh_key=user_key.public_key,
image_id=vm_image_id,
) )
# Create a Hosting Order # Create a Hosting Order
@ -567,21 +569,24 @@ class CreateVirtualMachinesView(LoginRequiredMixin, View):
) )
return HttpResponseRedirect(reverse('hosting:key_pair')) return HttpResponseRedirect(reverse('hosting:key_pair'))
#TODO: Replace with OpenNebulaManager.get_apps manager = OpenNebulaManager()
templates = OpenNebulaManager().get_templates() templates = manager.get_templates()
data = VirtualMachineTemplateSerializer(templates, many=True).data images = manager.get_images()
context = { context = {
'templates': data, 'templates': VirtualMachineTemplateSerializer(templates, many=True).data,
'images' : ImageSerializer(images, many=True).data
} }
# context = {}
return render(request, self.template_name, context) return render(request, self.template_name, context)
def post(self, request): def post(self, request):
template_id = int(request.POST.get('vm_template_id')) manager = OpenNebulaManager()
template = OpenNebulaManager().get_template(template_id) template_id = request.POST.get('vm_template_id')
data = VirtualMachineTemplateSerializer(template).data template = manager.get_template(template_id)
request.session['template'] = data image_id = request.POST.get('vm_image_id')
image = manager.get_image(image_id)
request.session['template'] = VirtualMachineTemplateSerializer(template).data
request.session['image'] = ImageSerializer(image).data
return redirect(reverse('hosting:payment')) return redirect(reverse('hosting:payment'))

View file

@ -102,23 +102,43 @@ class OpenNebulaManager():
return [] return []
def get_vm(self, vm_id): def get_vm(self, vm_id):
vm_id = int(vm_id)
try: try:
vm_pool = self._get_vm_pool() vm_pool = self._get_vm_pool()
return vm_pool.get_by_id(int(vm_id)) return vm_pool.get_by_id(vm_id)
except: except:
return None return None
#TODO: get app with id def create_vm(self, template_id, image_id=None, ssh_key=None):
def create_vm(self, template_id, app_id=None, ssh_key=None): extra_template_formater = """<CONTEXT>
extra_template = "<CONTEXT><SSH_PUBLIC_KEY>{ssh_key}</SSH_PUBLIC_KEY></CONTEXT>".format( <SSH_PUBLIC_KEY>{ssh_key}</SSH_PUBLIC_KEY>
ssh_key=ssh_key </CONTEXT>
<DISK>
<IMAGE_ID>{image_id}</IMAGE_ID>
</DISK>
"""
template = self.get_template(template_id)
vm_id = template.instantiate(name ='', pending=False, extra_template='')
image = self.get_image(image_id)
image_name = "{image_name}{template_name}{vm_id}".format(
image_name=image.name,
template_name=template.name,
vm_id = vm_id,
) )
vm_id = self.oneadmin_client.call(
oca.VmTemplate.METHODS['instantiate'], image_id = image.clone(name=image_name)
template_id,
'', self.oneadmin_client.call(
False, oca.VmTemplate.METHODS['update'],
extra_template vm_id,
extra_template_formater.format(
ssh_key=ssh_key,
image_id=image_id
),
# 0 = Replace / 1 = Merge
1,
) )
try: try:
self.oneadmin_client.call( self.oneadmin_client.call(
@ -177,8 +197,12 @@ class OpenNebulaManager():
return [] return []
def get_template(self, template_id): def get_template(self, template_id):
template_id = int(template_id)
try:
template_pool = self._get_template_pool() template_pool = self._get_template_pool()
return template_pool.get_by_id(template_id) return template_pool.get_by_id(template_id)
except:
return None
@ -238,3 +262,38 @@ class OpenNebulaManager():
self.opennebula_user.id, self.opennebula_user.id,
new_password new_password
) )
def _get_image_pool(self):
try:
image_pool = oca.ImagePool(self.oneadmin_client)
image_pool.info()
#TODO: Replace with logger
except ConnectionRefusedError:
logger.info('Could not connect to host: {host} via protocol {protocol}'.format(
host=settings.OPENNEBULA_DOMAIN,
protocol=settings.OPENNEBULA_PROTOCOL)
)
raise ConnectionRefusedError
return image_pool
def get_images(self):
try:
public_images = [
image
for image in self._get_image_pool()
if 'public-' in image.name
]
return public_images
except ConnectionRefusedError:
return []
pass
def get_image(self, image_id):
image_id = int(image_id)
try:
image_pool = self._get_image_pool()
return image_pool.get_by_id(image_id)
except:
return None

View file

@ -31,7 +31,7 @@ class VirtualMachineTemplateSerializer(serializers.Serializer):
core_price = template.pop('cpu_cost') core_price = template.pop('cpu_cost')
memory_price = template.pop('memory_cost') memory_price = template.pop('memory_cost')
disk_size_price = template.pop('disk_cost') disk_size_price = template.pop('disk_cost')
manager = OpenNebulaManager(create_user = False) manager = OpenNebulaManager()
try: try:
opennebula_id = manager.create_template(name=name, cores=cores, opennebula_id = manager.create_template(name=name, cores=cores,
@ -92,7 +92,7 @@ class VirtualMachineSerializer(serializers.Serializer):
try: try:
manager = OpenNebulaManager(email=owner.email, manager = OpenNebulaManager(email=owner.email,
password=owner.password, password=owner.password,
create_user = True) )
opennebula_id = manager.create_vm(template_id) opennebula_id = manager.create_vm(template_id)
except OpenNebulaException as err: except OpenNebulaException as err:
raise serializers.ValidationError("OpenNebulaException occured. {0}".format(err)) raise serializers.ValidationError("OpenNebulaException occured. {0}".format(err))
@ -117,3 +117,8 @@ class VirtualMachineSerializer(serializers.Serializer):
price += int(disk.size)/1024 * float(template.disk_cost) price += int(disk.size)/1024 * float(template.disk_cost)
return price return price
class ImageSerializer(serializers.Serializer):
"""Serializer to map the image instance into JSON format."""
id = serializers.IntegerField(read_only=True)
name = serializers.CharField()

View file

@ -47,8 +47,7 @@ class VmCreateView(generics.ListCreateAPIView):
def get_queryset(self): def get_queryset(self):
owner = self.request.user owner = self.request.user
manager = OpenNebulaManager(email=owner.email, manager = OpenNebulaManager(email=owner.email,
password=owner.password, password=owner.password)
create_user=True)
return manager.get_vms() return manager.get_vms()
def perform_create(self, serializer): def perform_create(self, serializer):
@ -64,21 +63,18 @@ class VmDetailsView(generics.RetrieveUpdateDestroyAPIView):
def get_queryset(self): def get_queryset(self):
owner = self.request.user owner = self.request.user
manager = OpenNebulaManager(email=owner.email, manager = OpenNebulaManager(email=owner.email,
password=owner.password, password=owner.password)
create_user=True)
return manager.get_vms() return manager.get_vms()
def get_object(self): def get_object(self):
owner = self.request.user owner = self.request.user
manager = OpenNebulaManager(email=owner.email, manager = OpenNebulaManager(email=owner.email,
password=owner.password, password=owner.password)
create_user=True)
return manager.get_vm(self.kwargs.get('pk')) return manager.get_vm(self.kwargs.get('pk'))
def perform_destroy(self, instance): def perform_destroy(self, instance):
owner = self.request.user owner = self.request.user
manager = OpenNebulaManager(email=owner.email, manager = OpenNebulaManager(email=owner.email,
password=owner.password, password=owner.password)
create_user = True)
manager.delete_vm(instance.id) manager.delete_vm(instance.id)