diff --git a/hosting/views.py b/hosting/views.py
index 3999037b..af86b825 100644
--- a/hosting/views.py
+++ b/hosting/views.py
@@ -31,7 +31,7 @@ from .mixins import ProcessVMSelectionMixin
from opennebula_api.models import OpenNebulaManager
from opennebula_api.serializers import VirtualMachineSerializer,\
- VirtualMachineTemplateSerializer
+ VirtualMachineTemplateSerializer
from oca.exceptions import OpenNebulaException
@@ -40,6 +40,7 @@ from oca.pool import WrongNameError
CONNECTION_ERROR = "Your VMs cannot be displayed at the moment due to a backend \
connection error. please try again in a few minutes."
+
class DjangoHostingView(ProcessVMSelectionMixin, View):
template_name = "hosting/django.html"
@@ -189,7 +190,8 @@ class SignupView(CreateView):
model = CustomUser
def get_success_url(self):
- next_url = self.request.session.get('next', reverse_lazy('hosting:virtual_machines'))
+ next_url = self.request.session.get(
+ 'next', reverse_lazy('hosting:virtual_machines'))
return next_url
def form_valid(self, form):
@@ -243,12 +245,14 @@ class PasswordResetConfirmView(PasswordResetConfirmViewMixin):
return self.form_valid(form)
else:
- messages.error(request, 'Password reset has not been successful.')
+ messages.error(
+ request, 'Password reset has not been successful.')
form.add_error(None, 'Password reset has not been successful.')
return self.form_invalid(form)
else:
- messages.error(request, 'The reset password link is no longer valid.')
+ messages.error(
+ request, 'The reset password link is no longer valid.')
form.add_error(None, 'The reset password link is no longer valid.')
return self.form_invalid(form)
@@ -337,7 +341,20 @@ class GenerateVMSSHKeysView(LoginRequiredMixin, FormView):
'form': UserHostingKeyForm(request=self.request),
})
- # return HttpResponseRedirect(reverse('hosting:key_pair'))
+ owner = self.request.user
+ # Create OpenNebulaManager
+ manager = OpenNebulaManager(email=owner.email,
+ password=owner.password)
+ # Get OpenNebula user id
+ user_pool = manager._get_user_pool()
+ opennebula_user = user_pool.get_by_name(owner.email)
+
+ # Get user ssh key
+ user_key = UserHostingKey.objects.get(user=owner)
+ # Add ssh key to user
+ manager.oneadmin_client.call('user.update', opennebula_user.id,
+ '{ssh_key}'.format(ssh_key=user_key.public_key))
+
return render(self.request, self.template_name, context)
def post(self, request, *args, **kwargs):
@@ -385,9 +402,11 @@ class PaymentVMView(LoginRequiredMixin, FormView):
user = self.request.user
# Get user last order
- last_hosting_order = HostingOrder.objects.filter(customer__user=user).last()
+ last_hosting_order = HostingOrder.objects.filter(
+ customer__user=user).last()
- # If user has already an hosting order, get the credit card data from it
+ # If user has already an hosting order, get the credit card data from
+ # it
if last_hosting_order:
credit_card_data = last_hosting_order.get_cc_data()
context.update({
@@ -475,12 +494,11 @@ class PaymentVMView(LoginRequiredMixin, FormView):
except UserHostingKey.DoesNotExist:
pass
-
# Create a vm using logged user
vm_id = manager.create_vm(
template_id=vm_template_id,
- #XXX: Confi
+ # XXX: Confi
specs=specs,
ssh_key=user_key.public_key,
)
@@ -494,14 +512,16 @@ class PaymentVMView(LoginRequiredMixin, FormView):
)
# Create a Hosting Bill
- bill = HostingBill.create(customer=customer, billing_address=billing_address)
+ 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 = UserBillingAddressForm(
+ billing_address_data)
billing_address_user_form.is_valid()
billing_address_user_form.save()
@@ -553,9 +573,9 @@ class OrdersHostingDetailView(PermissionRequiredMixin, LoginRequiredMixin, Detai
vm = manager.get_vm(obj.vm_id)
context['vm'] = VirtualMachineSerializer(vm).data
except ConnectionRefusedError:
- messages.error( request,
- 'In order to create a VM, you need to create/upload your SSH KEY first.'
- )
+ messages.error(request,
+ 'In order to create a VM, you need to create/upload your SSH KEY first.'
+ )
return context
@@ -595,20 +615,19 @@ class VirtualMachinesPlanListView(LoginRequiredMixin, ListView):
serializer = VirtualMachineSerializer(queryset, many=True)
return serializer.data
except ConnectionRefusedError:
- messages.error( self.request,
- 'We could not load your VMs due to a backend connection \
+ messages.error(self.request,
+ 'We could not load your VMs due to a backend connection \
error. Please try again in a few minutes'
- )
+ )
self.kwargs['error'] = 'connection'
return []
-
def get_context_data(self, **kwargs):
error = self.kwargs.get('error')
if error is not None:
print(error)
- context = { 'error' : 'connection' }
+ context = {'error': 'connection'}
else:
context = super(ListView, self).get_context_data(**kwargs)
return context
@@ -658,9 +677,10 @@ class CreateVirtualMachinesView(LoginRequiredMixin, View):
template = manager.get_template(template_id)
configuration_id = int(request.POST.get('configuration'))
configuration = HostingPlan.objects.get(id=configuration_id)
- request.session['template'] = VirtualMachineTemplateSerializer(template).data
+ request.session['template'] = VirtualMachineTemplateSerializer(
+ template).data
- request.session['specs'] = configuration.serialize()
+ request.session['specs'] = configuration.serialize()
return redirect(reverse('hosting:payment'))
@@ -680,10 +700,10 @@ class VirtualMachineView(LoginRequiredMixin, View):
vm = manager.get_vm(vm_id)
return vm
except ConnectionRefusedError:
- messages.error( self.request,
- 'We could not load your VM due to a backend connection \
+ messages.error(self.request,
+ 'We could not load your VM due to a backend connection \
error. Please try again in a few minutes'
- )
+ )
return None
except Exception as error:
print(error)
@@ -695,7 +715,7 @@ class VirtualMachineView(LoginRequiredMixin, View):
def get(self, request, *args, **kwargs):
vm = self.get_object()
- try:
+ try:
serializer = VirtualMachineSerializer(vm)
context = {
'virtual_machine': serializer.data,
diff --git a/opennebula_api/models.py b/opennebula_api/models.py
index 0c4e521b..3eac0b6e 100644
--- a/opennebula_api/models.py
+++ b/opennebula_api/models.py
@@ -10,17 +10,18 @@ from oca.pool import WrongNameError
from oca.exceptions import OpenNebulaException
logger = logging.getLogger(__name__)
+
class OpenNebulaManager():
"""This class represents an opennebula manager."""
def __init__(self, email=None, password=None):
-
+
# Get oneadmin client
self.oneadmin_client = self._get_opennebula_client(
settings.OPENNEBULA_USERNAME,
settings.OPENNEBULA_PASSWORD
)
-
+
# Get or create oppenebula user using given credentials
try:
self.opennebula_user = self._get_or_create_user(
@@ -55,26 +56,27 @@ class OpenNebulaManager():
opennebula_user = self.oneadmin_client.call(oca.User.METHODS['allocate'], email,
password, 'core')
logger.debug(
- "User {0} does not exist. Created the user. User id = {1}",
- email,
- opennebula_user
- )
+ "User {0} does not exist. Created the user. User id = {1}",
+ email,
+ opennebula_user
+ )
return opennebula_user
except ConnectionRefusedError:
logger.info('Could not connect to host: {host} via protocol {protocol}'.format(
- host=settings.OPENNEBULA_DOMAIN,
- protocol=settings.OPENNEBULA_PROTOCOL)
- )
+ host=settings.OPENNEBULA_DOMAIN,
+ protocol=settings.OPENNEBULA_PROTOCOL)
+ )
raise ConnectionRefusedError
+
def _get_user_pool(self):
try:
user_pool = oca.UserPool(self.oneadmin_client)
user_pool.info()
except ConnectionRefusedError:
logger.info('Could not connect to host: {host} via protocol {protocol}'.format(
- host=settings.OPENNEBULA_DOMAIN,
- protocol=settings.OPENNEBULA_PROTOCOL)
- )
+ host=settings.OPENNEBULA_DOMAIN,
+ protocol=settings.OPENNEBULA_PROTOCOL)
+ )
raise ConnectionRefusedError
return user_pool
@@ -84,7 +86,7 @@ class OpenNebulaManager():
vm_pool.info()
return vm_pool
except AttributeError:
- logger.info('Could not connect via client, using oneadmin instead')
+ logger.info('Could not connect via client, using oneadmin instead')
try:
vm_pool = oca.VirtualMachinePool(self.oneadmin_client)
vm_pool.info(filter=-2)
@@ -94,9 +96,9 @@ class OpenNebulaManager():
except ConnectionRefusedError:
logger.info('Could not connect to host: {host} via protocol {protocol}'.format(
- host=settings.OPENNEBULA_DOMAIN,
- protocol=settings.OPENNEBULA_PROTOCOL)
- )
+ host=settings.OPENNEBULA_DOMAIN,
+ protocol=settings.OPENNEBULA_PROTOCOL)
+ )
raise ConnectionRefusedError
# For now we'll just handle all other errors as connection errors
except:
@@ -107,8 +109,7 @@ class OpenNebulaManager():
return self._get_vm_pool()
except ConnectionRefusedError:
raise ConnectionRefusedError
-
-
+
def get_vm(self, vm_id):
vm_id = int(vm_id)
try:
@@ -118,7 +119,7 @@ class OpenNebulaManager():
raise ConnectionRefusedError
def create_template(self, name, cores, memory, disk_size, core_price, memory_price,
- disk_size_price, ssh='' ):
+ disk_size_price, ssh=''):
"""Create and add a new template to opennebula.
:param name: A string representation describing the template.
Used as label in view.
@@ -130,17 +131,17 @@ class OpenNebulaManager():
:param disk_size_price: Price of disk space for VM per GB
:param ssh: User public ssh key
"""
-
+
template_id = oca.VmTemplate.allocate(
self.oneadmin_client,
template_string_formatter.format(
name=name,
vcpu=cores,
- cpu=0.1*cores,
+ cpu=0.1 * cores,
size=1024 * disk_size,
memory=1024 * memory,
# * 10 because we set cpu to *0.1
- cpu_cost=10*core_price,
+ cpu_cost=10 * core_price,
memory_cost=memory_price,
disk_cost=disk_size_price,
ssh=ssh
@@ -159,11 +160,11 @@ class OpenNebulaManager():
disk = template.template.disks[0]
image_id = disk.image_id
vm_specs = vm_specs_formatter.format(
- vcpu=int(specs['cpu']),
- cpu=0.1* int(specs['cpu']),
- memory=1024 * int(specs['memory']),
-
- )
+ vcpu=int(specs['cpu']),
+ cpu=0.1 * int(specs['cpu']),
+ memory=1024 * int(specs['memory']),
+
+ )
vm_specs += """
fs
{size}
@@ -180,11 +181,11 @@ class OpenNebulaManager():
image_uname = disk.image_uname
vm_specs = vm_specs_formatter.format(
- vcpu=int(specs['cpu']),
- cpu=0.1* int(specs['cpu']),
- memory=1024 * int(specs['memory']),
-
- )
+ vcpu=int(specs['cpu']),
+ cpu=0.1 * int(specs['cpu']),
+ memory=1024 * int(specs['memory']),
+
+ )
vm_specs += """
fs
{size}
@@ -196,18 +197,21 @@ class OpenNebulaManager():
""".format(size=1024 * int(specs['disk_size']),
image=image,
image_uname=image_uname)
- vm_id = template.instantiate(name ='',
- pending=False,
- extra_template=vm_specs, )
+ vm_id = self.client.call(oca.VmTemplate.METHODS['instantiate'],
+ template.id,
+ '',
+ True,
+ vm_specs,
+ False)
self.oneadmin_client.call(
- 'vm.updateconf',
+ 'vm.update',
vm_id,
"""
{ssh}
""".format(ssh=ssh_key)
- )
+ )
try:
self.oneadmin_client.call(
oca.VirtualMachine.METHODS['chown'],
@@ -216,7 +220,14 @@ class OpenNebulaManager():
self.opennebula_user.group_ids[0]
)
except AttributeError:
- logger.info('Could not change owner for vm with id: {}.'.format(vm_id))
+ logger.info(
+ 'Could not change owner for vm with id: {}.'.format(vm_id))
+
+ self.oneadmin_client.call(
+ oca.VirtualMachine.METHODS['action'],
+ 'release',
+ vm_id
+ )
return vm_id
def delete_vm(self, vm_id):
@@ -232,7 +243,8 @@ class OpenNebulaManager():
except socket.timeout as socket_err:
logger.info("Socket timeout error: {0}".format(socket_err))
except OpenNebulaException as opennebula_err:
- logger.info("OpenNebulaException error: {0}".format(opennebula_err))
+ logger.info(
+ "OpenNebulaException error: {0}".format(opennebula_err))
except OSError as os_err:
logger.info("OSError : {0}".format(os_err))
except ValueError as value_err:
@@ -242,27 +254,26 @@ class OpenNebulaManager():
def _get_template_pool(self):
try:
- template_pool = oca.VmTemplatePool(self.oneadmin_client)
- template_pool.info()
- return template_pool
+ template_pool = oca.VmTemplatePool(self.oneadmin_client)
+ template_pool.info()
+ return template_pool
except ConnectionRefusedError:
logger.info('Could not connect to host: {host} via protocol {protocol}'.format(
- host=settings.OPENNEBULA_DOMAIN,
- protocol=settings.OPENNEBULA_PROTOCOL)
- )
+ host=settings.OPENNEBULA_DOMAIN,
+ protocol=settings.OPENNEBULA_PROTOCOL)
+ )
raise ConnectionRefusedError
except:
raise ConnectionRefusedError
-
def get_templates(self):
try:
public_templates = [
- template
- for template in self._get_template_pool()
- if 'public-' in template.name
- ]
- return public_templates
+ template
+ for template in self._get_template_pool()
+ if 'public-' in template.name
+ ]
+ return public_templates
except ConnectionRefusedError:
raise ConnectionRefusedError
except:
@@ -282,10 +293,8 @@ class OpenNebulaManager():
except:
raise ConnectionRefusedError
-
-
def create_template(self, name, cores, memory, disk_size, core_price, memory_price,
- disk_size_price, ssh='' ):
+ disk_size_price, ssh=''):
"""Create and add a new template to opennebula.
:param name: A string representation describing the template.
Used as label in view.
@@ -318,11 +327,11 @@ class OpenNebulaManager():
template_string_formatter.format(
name=name,
vcpu=cores,
- cpu=0.1*cores,
+ cpu=0.1 * cores,
size=1024 * disk_size,
memory=1024 * memory,
# * 10 because we set cpu to *0.1
- cpu_cost=10*core_price,
+ cpu_cost=10 * core_price,
memory_cost=memory_price,
disk_cost=disk_size_price,
ssh=ssh
@@ -332,11 +341,12 @@ class OpenNebulaManager():
return template_id
def delete_template(self, template_id):
- self.oneadmin_client.call(oca.VmTemplate.METHODS['delete'], template_id, False)
+ self.oneadmin_client.call(oca.VmTemplate.METHODS[
+ 'delete'], template_id, False)
def change_user_password(self, new_password):
self.oneadmin_client.call(
oca.User.METHODS['passwd'],
self.opennebula_user.id,
new_password
- )
+ )