Some more fixes for the issues of the review of rscnt.

This commit is contained in:
M.Ravi 2017-04-25 03:37:50 +05:30
parent a8952700d6
commit 1e61ec965d
4 changed files with 106 additions and 111 deletions

View file

@ -6,10 +6,8 @@ Copyright 2015 ungleich.
# Build paths inside the project like this: os.path.join(BASE_DIR, ...) # Build paths inside the project like this: os.path.join(BASE_DIR, ...)
import os import os
from django.utils.translation import ugettext_lazy as _
# dotenv
import dotenv import dotenv
from django.utils.translation import ugettext_lazy as _
gettext = lambda s: s gettext = lambda s: s
@ -492,10 +490,7 @@ OPENNEBULA_PASSWORD = 'opennebula'
OPENNEBULA_PROTOCOL = 'http' OPENNEBULA_PROTOCOL = 'http'
# The ip address or the domain name of the opennebula infrastructure # The ip address or the domain name of the opennebula infrastructure
# OPENNEBULA_DOMAIN = '192.168.182.173' OPENNEBULA_DOMAIN = '192.168.182.124'
# OPENNEBULA_DOMAIN = '192.168.122.225'
# OPENNEBULA_DOMAIN = '192.168.182.176'
OPENNEBULA_DOMAIN = '192.168.42.35'
# The port to connect in order to send an xmlrpc request. The default # The port to connect in order to send an xmlrpc request. The default
# port is 2633 # port is 2633
@ -503,4 +498,4 @@ OPENNEBULA_PORT = '2633'
# The endpoint to which the XML RPC request needs to be sent to. The # The endpoint to which the XML RPC request needs to be sent to. The
# default value is /RPC2 # default value is /RPC2
OPENNEBULA_ENDPOINT = '/RPC2' OPENNEBULA_ENDPOINT = '/RPC2'

View file

@ -1,13 +1,12 @@
from django.contrib import admin from django.contrib import admin
from django.utils.html import format_html
from django.core.urlresolvers import reverse from django.core.urlresolvers import reverse
from django.utils.html import format_html
from utils.mailer import BaseEmail from utils.mailer import BaseEmail
from django.contrib.auth.signals import user_logged_in
from .forms import HostingOrderAdminForm from .forms import HostingOrderAdminForm
from .models import VirtualMachineType, VirtualMachinePlan, HostingOrder, ManageVM from .models import VirtualMachineType, VirtualMachinePlan, HostingOrder, ManageVM
from .opennebula_functions import HostingManageVMAdmin, user_logged_in_callback from .opennebula_functions import HostingManageVMAdmin
class HostingOrderAdmin(admin.ModelAdmin): class HostingOrderAdmin(admin.ModelAdmin):
# fields = ('slug', 'imdb_link', 'start', 'finish', 'added_by') # fields = ('slug', 'imdb_link', 'start', 'finish', 'added_by')
@ -97,6 +96,4 @@ class VirtualMachinePlanAdmin(admin.ModelAdmin):
admin.site.register(HostingOrder, HostingOrderAdmin) admin.site.register(HostingOrder, HostingOrderAdmin)
admin.site.register(VirtualMachineType) admin.site.register(VirtualMachineType)
admin.site.register(VirtualMachinePlan, VirtualMachinePlanAdmin) admin.site.register(VirtualMachinePlan, VirtualMachinePlanAdmin)
admin.site.register(ManageVM, HostingManageVMAdmin)
user_logged_in.connect(user_logged_in_callback)
admin.site.register(ManageVM, HostingManageVMAdmin)

View file

@ -1,15 +1,13 @@
import os import os
from django.db import models
from django.utils.translation import ugettext_lazy as _
from django.utils.functional import cached_property
from Crypto.PublicKey import RSA from Crypto.PublicKey import RSA
from django.db import models
from django.utils.functional import cached_property
from stored_messages.settings import stored_messages_settings from stored_messages.settings import stored_messages_settings
from membership.models import StripeCustomer from membership.models import StripeCustomer
from utils.models import BillingAddress
from utils.mixins import AssignPermissionsMixin from utils.mixins import AssignPermissionsMixin
from utils.models import BillingAddress
from .managers import VMPlansManager from .managers import VMPlansManager
@ -225,7 +223,6 @@ class HostingOrder(AssignPermissionsMixin, models.Model):
class ManageVM(models.Model): class ManageVM(models.Model):
#name = models.TextField(blank=True)
def has_add_permission(self, request): def has_add_permission(self, request):
return False return False

View file

@ -1,16 +1,18 @@
import logging import logging
import random
import socket import socket
import string import string
import oca import oca
import random
from django.conf import settings from django.conf import settings
from django.conf.urls import url from django.conf.urls import url
from django.contrib import admin from django.contrib import admin
from django.contrib import messages from django.contrib import messages
from django.shortcuts import redirect from django.shortcuts import redirect
from django.template.response import TemplateResponse from django.template.response import TemplateResponse
from django.utils.translation import ugettext_lazy as _
from oca.exceptions import OpenNebulaException from oca.exceptions import OpenNebulaException
from oca.pool import WrongNameError
# Get an instance of a logger # Get an instance of a logger
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@ -18,6 +20,7 @@ logger = logging.getLogger(__name__)
class HostingManageVMAdmin(admin.ModelAdmin): class HostingManageVMAdmin(admin.ModelAdmin):
client = None client = None
oneadmin_client = None
def get_urls(self): def get_urls(self):
urls = super().get_urls() urls = super().get_urls()
@ -34,8 +37,27 @@ class HostingManageVMAdmin(admin.ModelAdmin):
# Function to initialize opennebula client based on the logged in # Function to initialize opennebula client based on the logged in
# user # user
def init_opennebula_client(self, opennebula_user): def init_opennebula_client(self, request):
if self.oneadmin_client is None:
self.oneadmin_client = oca.Client("{0}:{1}".format(settings.OPENNEBULA_USERNAME,
settings.OPENNEBULA_PASSWORD),
"{protocol}://{domain}:{port}{endpoint}".format(
protocol=settings.OPENNEBULA_PROTOCOL,
domain=settings.OPENNEBULA_DOMAIN,
port=settings.OPENNEBULA_PORT,
endpoint=settings.OPENNEBULA_ENDPOINT
))
print("{0}:{1}".format(settings.OPENNEBULA_USERNAME,
settings.OPENNEBULA_PASSWORD))
print("{protocol}://{domain}:{port}{endpoint}".format(
protocol=settings.OPENNEBULA_PROTOCOL,
domain=settings.OPENNEBULA_DOMAIN,
port=settings.OPENNEBULA_PORT,
endpoint=settings.OPENNEBULA_ENDPOINT
))
self.create_opennebula_user(request)
if self.client is None: if self.client is None:
opennebula_user = request.user.email
opennebula_user_password = get_random_password() opennebula_user_password = get_random_password()
self.client = oca.Client("{0}:{1}".format(opennebula_user, opennebula_user_password), self.client = oca.Client("{0}:{1}".format(opennebula_user, opennebula_user_password),
"{protocol}://{domain}:{port}{endpoint}".format( "{protocol}://{domain}:{port}{endpoint}".format(
@ -49,26 +71,24 @@ class HostingManageVMAdmin(admin.ModelAdmin):
def show_vms(self, request): def show_vms(self, request):
vm_pool = None vm_pool = None
try: try:
self.init_opennebula_client(request.user) self.init_opennebula_client(request)
vm_pool = oca.VirtualMachinePool(self.client) vm_pool = oca.VirtualMachinePool(self.client)
vm_pool.info() vm_pool.info()
except socket.timeout: except socket.timeout:
messages.add_message(request, messages.ERROR, "Socket timeout error.") messages.add_message(request, messages.ERROR, _("Socket timeout error."))
except OpenNebulaException: except OpenNebulaException as opennebula_err:
messages.add_message(request, messages.ERROR, "OpenNebulaException occurred.") messages.add_message(request, messages.ERROR, _("OpenNebulaException occurred. {0}".format(opennebula_err)))
except OSError as err: except OSError as err:
messages.add_message(request, messages.ERROR, str("OS error: {0}".format(err))) messages.add_message(request, messages.ERROR, "OS error: {0}".format(err))
context = dict( context = dict(
# Include common variables for rendering the admin template. # Include common variables for rendering the admin template.
self.admin_site.each_context(request), self.admin_site.each_context(request),
vms=vm_pool, vms=vm_pool,
) )
return TemplateResponse(request, "hosting/managevms.html", context) return TemplateResponse(request, "hosting/managevms.html", context)
# Creating VM by using method allocate(client, template) # Creating VM by using method allocate(client, template)
def create_vm(self, request): def create_vm(self, request):
message = ''
# check if the request contains the template parameter, if it is # check if the request contains the template parameter, if it is
# not set warn the user of setting this. # not set warn the user of setting this.
vm_template = request.POST.get('vm_template') vm_template = request.POST.get('vm_template')
@ -82,24 +102,13 @@ class HostingManageVMAdmin(admin.ModelAdmin):
# the basic template of 10GB disk, 1GB ram, 1 vcpu, 0.1 cpu # the basic template of 10GB disk, 1GB ram, 1 vcpu, 0.1 cpu
vm_template_int = int(vm_template) vm_template_int = int(vm_template)
if 1 <= vm_template_int <= 8: if 1 <= vm_template_int <= 8:
vm_string_formatter = """ vm_string_formatter = """<VM>
<VM> <MEMORY>{memory}</MEMORY>
<MEMORY> <VCPU>{vcpu}</VCPU>
{memory} <CPU>{cpu}</CPU>
</MEMORY>
<VCPU>
{vcpu}
</VCPU>
<CPU>
{cpu}
</CPU>
<DISK> <DISK>
<TYPE> <TYPE>{disk_type}</TYPE>
{disk_type} <SIZE>{size}</SIZE>
</TYPE>
<SIZE>
{size}
</SIZE>
</DISK> </DISK>
</VM> </VM>
""" """
@ -110,113 +119,110 @@ class HostingManageVMAdmin(admin.ModelAdmin):
cpu=0.1 * vm_template_int, cpu=0.1 * vm_template_int,
disk_type='fs', disk_type='fs',
size=10000 * vm_template_int)) size=10000 * vm_template_int))
message = "Created with id = " + str(vm_id) message = _("Created with id = " + str(vm_id))
messages.add_message(request, messages.SUCCESS, message) messages.add_message(request, messages.SUCCESS, message)
else: else:
messages.add_message(request, messages.ERROR, messages.add_message(request, messages.ERROR,
"Please select an appropriate value for vm template.") _("Please select an appropriate value for vm template."))
except socket.timeout as socket_err: except socket.timeout as socket_err:
messages.add_message(request, messages.ERROR, "Socket timeout error.") messages.add_message(request, messages.ERROR, _("Socket timeout error."))
logger.error("Socket timeout error: {0}".format(socket_err)) logger.error("Socket timeout error: {0}".format(socket_err))
except OpenNebulaException as opennebula_err: except OpenNebulaException as opennebula_err:
messages.add_message(request, messages.ERROR, "OpenNebulaException occurred.") messages.add_message(request, messages.ERROR,
_("OpenNebulaException occurred. {0}".format(opennebula_err)))
logger.error("OpenNebulaException error: {0}".format(opennebula_err)) logger.error("OpenNebulaException error: {0}".format(opennebula_err))
except OSError as os_err: except OSError as os_err:
messages.add_message(request, messages.ERROR, str("OS error: {0}".format(os_err))) messages.add_message(request, messages.ERROR, _("OS error: {0}".format(os_err)))
logger.error("OSError : {0}".format(os_err)) logger.error("OSError : {0}".format(os_err))
except ValueError as value_err: except ValueError as value_err:
messages.add_message(request, messages.ERROR, messages.add_message(request, messages.ERROR,
"Please select an appropriate value for vm template.") _("Please select an appropriate value for vm template."))
logger.error("ValueError : {0}".format(value_err)) logger.error("ValueError : {0}".format(value_err))
return redirect('admin:showvms') return redirect('admin:showvms')
# Retrives virtual machine pool information
def get_vms(self):
vm_pool = oca.VirtualMachinePool(self.client)
vm_pool.info()
return vm_pool
# Delete VM from the pool and DB by using method finalize() # Delete VM from the pool and DB by using method finalize()
def delete_vm(self, request, vmid): def delete_vm(self, request, vmid):
# get the desired vm from the pool
vm_id = int(vmid) vm_id = int(vmid)
# get the desired vm from the pool
logger.debug("Deleting vm with id {0}".format(vm_id))
vm = self.get_vm_by_id(vm_id) vm = self.get_vm_by_id(vm_id)
if vm == -1: if vm is None:
messages.add_message(request, messages.ERROR, "Did not find a vm with id = " + str(vm_id)) messages.add_message(request, messages.ERROR, _("Did not find a vm with id = {0}".format(vm_id)))
else: else:
print("Deleting vm_id = " + str(vm_id) + " state = " + vm.str_state) logger.debug("Deleting vm_id = " + str(vm_id) + " state = " + vm.str_state)
if vm.str_state == 'PENDING' or vm.str_state == 'POWEROFF' or vm.str_state == 'ACTIVE': if vm.str_state == 'PENDING' or vm.str_state == 'POWEROFF' or vm.str_state == 'ACTIVE':
vm.delete() vm.delete()
messages.add_message(request, messages.SUCCESS, messages.add_message(request, messages.SUCCESS,
"Deleted from " + vm.str_state + " state vm with id = " + str(vm_id)) _("Deleted from {0} state vm with id = {1}".format(vm.str_state, str(vm_id))))
else: else:
vm.finalize() vm.finalize()
messages.add_message(request, messages.SUCCESS, messages.add_message(request, messages.SUCCESS,
"Deleted (using finalize()) from " + vm.str_state + " state vm with id = " + str( _("Deleted (using finalize()) from {0} state vm with id = {1}".format(vm.str_state,
vm_id)) str(vm_id))))
return redirect('admin:showvms') return redirect('admin:showvms')
def stop_vm(self, request, vmid): def stop_vm(self, request, vmid):
vm_id = int(vmid) vm_id = int(vmid)
vm = self.get_vm_by_id(vm_id) vm = self.get_vm_by_id(vm_id)
if vm == -1: if vm is None:
messages.add_message(request, messages.ERROR, "Did not find a vm with id = " + str(vm_id)) messages.add_message(request, messages.ERROR, _("Did not find a vm with id = {0}", vm_id))
else: else:
vm.stop() vm.stop()
messages.add_message(request, messages.SUCCESS, "Stopped the vm with id = " + str(vm_id)) messages.add_message(request, messages.SUCCESS, _("Stopped the vm with id = {0}", vm_id))
return redirect('admin:showvms') return redirect('admin:showvms')
def start_vm(self, request, vmid): def start_vm(self, request, vmid):
vm_id = int(vmid) vm_id = int(vmid)
vm = self.get_vm_by_id(vm_id) vm = self.get_vm_by_id(vm_id)
if vm == -1: if vm is None:
messages.add_message(request, messages.ERROR, "Did not find a vm with id = " + str(vm_id)) messages.add_message(request, messages.ERROR, _("Did not find a vm with id = {0}", vm_id))
else: else:
vm.resume() vm.resume()
messages.add_message(request, messages.SUCCESS, "Started the vm with id = " + str(vm_id)) messages.add_message(request, messages.SUCCESS, _("Started the vm with id = {0}", vm_id))
return redirect('admin:showvms') return redirect('admin:showvms')
# Retrives virtual machine pool information
def get_vm_pool(self):
vm_pool = oca.VirtualMachinePool(self.client)
vm_pool.info()
return vm_pool
def get_vm_by_id(self, vmid): def get_vm_by_id(self, vmid):
vms = self.get_vms() vm_pool = self.get_vm_pool()
for vm in vms: return vm_pool.get_by_id(vmid)
if vm.id == vmid:
return vm
return -1
def create_opennebula_user(self, request):
# callback for creating opennebula users on user login # Notes:
def user_logged_in_callback(sender, request, user, **kwargs): # 1. python-oca library's oca.User.allocate(client, user, pass)
client = oca.Client(settings.OPENNEBULA_USERNAME + ':' + settings.OPENNEBULA_PASSWORD, # method does not work with python-oca version oca-4.15.0a1-py3.5
settings.OPENNEBULA_PROTOCOL + '://' + settings.OPENNEBULA_DOMAIN + ':' + settings.OPENNEBULA_PORT + settings.OPENNEBULA_ENDPOINT) # This is because the call is missing a fourth parameter
# Notes: # auth_driver.
# 1. python-oca library's oca.User.allocate(client, user, pass) # To overcome this issue, we make a direct call to xml-rpc method
# method does not work with python-oca version oca-4.15.0a1-py3.5 # 'user.allocate' passing this fourth parameter.
# This is because the call is missing a fourth parameter #
# auth_driver. # 2. We have a dummy authentication driver in opennebula and we
# To overcome this issue, we make a direct call to xml-rpc method # use this so as to avoid opennebula authentication. However, we
# 'user.allocate' passing this fourth parameter. # need to supply a dummy password. Without this, we can not
# # create an OpenNebula user. We use dummy string 'a' as password
# 2. We have a dummy authentication driver in opennebula and we # for all users.
# use this so as to avoid opennebula authentication. However, we #
# need to supply a dummy password. Without this, we can not # 3. We user the user's email as the user name.
# create an OpenNebula user. We use dummy string 'a' as password # 4. If the user's email is not registered with OpenNebula,
# for all users. # WrongNameError is raised. We create an OpenNebula user in
# # such case.
# 3. We user the user's email as the user name. try:
if find_opennebula_user_by_name(str(user.email), client) == -1: user_pool = oca.UserPool(self.oneadmin_client)
user_id = client.call('user.allocate', str(user.email), get_random_password(), 'dummy') user_pool.info()
print("User " + str(user.email) + " does not exist. Created the user. User id = " + str(user_id)) opennebula_user = user_pool.get_by_name(request.user.email)
logger.debug("User {0} exists. User id = {1}".format(request.user.email, opennebula_user.id))
except WrongNameError as wrong_name_err:
# Finds if an OpenNebula user with user_name exists. Returns the user_id = self.oneadmin_client.call('user.allocate', request.user.email, get_random_password(),
# OpenNebula user if it exists, -1 otherwise. 'dummy')
def find_opennebula_user_by_name(user_name, client): logger.debug("User {0} does not exist. Created the user. User id = {1}", request.user.email, user_id)
pool = oca.UserPool(client) except OpenNebulaException as err:
pool.info() messages.add_message(request, messages.ERROR,
for user in pool: "Error : {0}".format(err))
if user.name == user_name: logger.error("Error : {0}".format(err))
return user
return -1
# Returns random password that is needed by OpenNebula # Returns random password that is needed by OpenNebula