Merge pull request #276 from Modulos/develop
Add UserHosting public key to opennebula user
This commit is contained in:
commit
622cdbe732
2 changed files with 110 additions and 89 deletions
|
@ -31,7 +31,7 @@ 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
|
||||||
|
|
||||||
|
|
||||||
from oca.exceptions import OpenNebulaException
|
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 = "Your VMs cannot be displayed at the moment due to a backend \
|
||||||
connection error. please try again in a few minutes."
|
connection error. please try again in a few minutes."
|
||||||
|
|
||||||
|
|
||||||
class DjangoHostingView(ProcessVMSelectionMixin, View):
|
class DjangoHostingView(ProcessVMSelectionMixin, View):
|
||||||
template_name = "hosting/django.html"
|
template_name = "hosting/django.html"
|
||||||
|
|
||||||
|
@ -189,7 +190,8 @@ class SignupView(CreateView):
|
||||||
model = CustomUser
|
model = CustomUser
|
||||||
|
|
||||||
def get_success_url(self):
|
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
|
return next_url
|
||||||
|
|
||||||
def form_valid(self, form):
|
def form_valid(self, form):
|
||||||
|
@ -243,12 +245,14 @@ class PasswordResetConfirmView(PasswordResetConfirmViewMixin):
|
||||||
|
|
||||||
return self.form_valid(form)
|
return self.form_valid(form)
|
||||||
else:
|
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.')
|
form.add_error(None, 'Password reset has not been successful.')
|
||||||
return self.form_invalid(form)
|
return self.form_invalid(form)
|
||||||
|
|
||||||
else:
|
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.')
|
form.add_error(None, 'The reset password link is no longer valid.')
|
||||||
return self.form_invalid(form)
|
return self.form_invalid(form)
|
||||||
|
|
||||||
|
@ -337,7 +341,20 @@ class GenerateVMSSHKeysView(LoginRequiredMixin, FormView):
|
||||||
'form': UserHostingKeyForm(request=self.request),
|
'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,
|
||||||
|
'<CONTEXT><SSH_PUBLIC_KEY>{ssh_key}</SSH_PUBLIC_KEY></CONTEXT>'.format(ssh_key=user_key.public_key))
|
||||||
|
|
||||||
return render(self.request, self.template_name, context)
|
return render(self.request, self.template_name, context)
|
||||||
|
|
||||||
def post(self, request, *args, **kwargs):
|
def post(self, request, *args, **kwargs):
|
||||||
|
@ -385,9 +402,11 @@ class PaymentVMView(LoginRequiredMixin, FormView):
|
||||||
user = self.request.user
|
user = self.request.user
|
||||||
|
|
||||||
# Get user last order
|
# 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:
|
if last_hosting_order:
|
||||||
credit_card_data = last_hosting_order.get_cc_data()
|
credit_card_data = last_hosting_order.get_cc_data()
|
||||||
context.update({
|
context.update({
|
||||||
|
@ -476,11 +495,10 @@ class PaymentVMView(LoginRequiredMixin, FormView):
|
||||||
except UserHostingKey.DoesNotExist:
|
except UserHostingKey.DoesNotExist:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
# Create a vm using logged user
|
# Create a vm using logged user
|
||||||
vm_id = manager.create_vm(
|
vm_id = manager.create_vm(
|
||||||
template_id=vm_template_id,
|
template_id=vm_template_id,
|
||||||
#XXX: Confi
|
# XXX: Confi
|
||||||
specs=specs,
|
specs=specs,
|
||||||
ssh_key=user_key.public_key,
|
ssh_key=user_key.public_key,
|
||||||
)
|
)
|
||||||
|
@ -494,14 +512,16 @@ class PaymentVMView(LoginRequiredMixin, FormView):
|
||||||
)
|
)
|
||||||
|
|
||||||
# Create a Hosting Bill
|
# 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
|
# Create Billing Address for User if he does not have one
|
||||||
if not customer.user.billing_addresses.count():
|
if not customer.user.billing_addresses.count():
|
||||||
billing_address_data.update({
|
billing_address_data.update({
|
||||||
'user': customer.user.id
|
'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.is_valid()
|
||||||
billing_address_user_form.save()
|
billing_address_user_form.save()
|
||||||
|
|
||||||
|
@ -553,9 +573,9 @@ class OrdersHostingDetailView(PermissionRequiredMixin, LoginRequiredMixin, Detai
|
||||||
vm = manager.get_vm(obj.vm_id)
|
vm = manager.get_vm(obj.vm_id)
|
||||||
context['vm'] = VirtualMachineSerializer(vm).data
|
context['vm'] = VirtualMachineSerializer(vm).data
|
||||||
except ConnectionRefusedError:
|
except ConnectionRefusedError:
|
||||||
messages.error( request,
|
messages.error(request,
|
||||||
'In order to create a VM, you need to create/upload your SSH KEY first.'
|
'In order to create a VM, you need to create/upload your SSH KEY first.'
|
||||||
)
|
)
|
||||||
return context
|
return context
|
||||||
|
|
||||||
|
|
||||||
|
@ -595,20 +615,19 @@ class VirtualMachinesPlanListView(LoginRequiredMixin, ListView):
|
||||||
serializer = VirtualMachineSerializer(queryset, many=True)
|
serializer = VirtualMachineSerializer(queryset, many=True)
|
||||||
return serializer.data
|
return serializer.data
|
||||||
except ConnectionRefusedError:
|
except ConnectionRefusedError:
|
||||||
messages.error( self.request,
|
messages.error(self.request,
|
||||||
'We could not load your VMs due to a backend connection \
|
'We could not load your VMs due to a backend connection \
|
||||||
error. Please try again in a few minutes'
|
error. Please try again in a few minutes'
|
||||||
)
|
)
|
||||||
|
|
||||||
self.kwargs['error'] = 'connection'
|
self.kwargs['error'] = 'connection'
|
||||||
return []
|
return []
|
||||||
|
|
||||||
|
|
||||||
def get_context_data(self, **kwargs):
|
def get_context_data(self, **kwargs):
|
||||||
error = self.kwargs.get('error')
|
error = self.kwargs.get('error')
|
||||||
if error is not None:
|
if error is not None:
|
||||||
print(error)
|
print(error)
|
||||||
context = { 'error' : 'connection' }
|
context = {'error': 'connection'}
|
||||||
else:
|
else:
|
||||||
context = super(ListView, self).get_context_data(**kwargs)
|
context = super(ListView, self).get_context_data(**kwargs)
|
||||||
return context
|
return context
|
||||||
|
@ -658,7 +677,8 @@ class CreateVirtualMachinesView(LoginRequiredMixin, View):
|
||||||
template = manager.get_template(template_id)
|
template = manager.get_template(template_id)
|
||||||
configuration_id = int(request.POST.get('configuration'))
|
configuration_id = int(request.POST.get('configuration'))
|
||||||
configuration = HostingPlan.objects.get(id=configuration_id)
|
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'))
|
return redirect(reverse('hosting:payment'))
|
||||||
|
@ -680,10 +700,10 @@ class VirtualMachineView(LoginRequiredMixin, View):
|
||||||
vm = manager.get_vm(vm_id)
|
vm = manager.get_vm(vm_id)
|
||||||
return vm
|
return vm
|
||||||
except ConnectionRefusedError:
|
except ConnectionRefusedError:
|
||||||
messages.error( self.request,
|
messages.error(self.request,
|
||||||
'We could not load your VM due to a backend connection \
|
'We could not load your VM due to a backend connection \
|
||||||
error. Please try again in a few minutes'
|
error. Please try again in a few minutes'
|
||||||
)
|
)
|
||||||
return None
|
return None
|
||||||
except Exception as error:
|
except Exception as error:
|
||||||
print(error)
|
print(error)
|
||||||
|
|
|
@ -10,6 +10,7 @@ from oca.pool import WrongNameError
|
||||||
from oca.exceptions import OpenNebulaException
|
from oca.exceptions import OpenNebulaException
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
class OpenNebulaManager():
|
class OpenNebulaManager():
|
||||||
"""This class represents an opennebula manager."""
|
"""This class represents an opennebula manager."""
|
||||||
|
|
||||||
|
@ -55,26 +56,27 @@ class OpenNebulaManager():
|
||||||
opennebula_user = self.oneadmin_client.call(oca.User.METHODS['allocate'], email,
|
opennebula_user = self.oneadmin_client.call(oca.User.METHODS['allocate'], email,
|
||||||
password, 'core')
|
password, 'core')
|
||||||
logger.debug(
|
logger.debug(
|
||||||
"User {0} does not exist. Created the user. User id = {1}",
|
"User {0} does not exist. Created the user. User id = {1}",
|
||||||
email,
|
email,
|
||||||
opennebula_user
|
opennebula_user
|
||||||
)
|
)
|
||||||
return opennebula_user
|
return opennebula_user
|
||||||
except ConnectionRefusedError:
|
except ConnectionRefusedError:
|
||||||
logger.info('Could not connect to host: {host} via protocol {protocol}'.format(
|
logger.info('Could not connect to host: {host} via protocol {protocol}'.format(
|
||||||
host=settings.OPENNEBULA_DOMAIN,
|
host=settings.OPENNEBULA_DOMAIN,
|
||||||
protocol=settings.OPENNEBULA_PROTOCOL)
|
protocol=settings.OPENNEBULA_PROTOCOL)
|
||||||
)
|
)
|
||||||
raise ConnectionRefusedError
|
raise ConnectionRefusedError
|
||||||
|
|
||||||
def _get_user_pool(self):
|
def _get_user_pool(self):
|
||||||
try:
|
try:
|
||||||
user_pool = oca.UserPool(self.oneadmin_client)
|
user_pool = oca.UserPool(self.oneadmin_client)
|
||||||
user_pool.info()
|
user_pool.info()
|
||||||
except ConnectionRefusedError:
|
except ConnectionRefusedError:
|
||||||
logger.info('Could not connect to host: {host} via protocol {protocol}'.format(
|
logger.info('Could not connect to host: {host} via protocol {protocol}'.format(
|
||||||
host=settings.OPENNEBULA_DOMAIN,
|
host=settings.OPENNEBULA_DOMAIN,
|
||||||
protocol=settings.OPENNEBULA_PROTOCOL)
|
protocol=settings.OPENNEBULA_PROTOCOL)
|
||||||
)
|
)
|
||||||
raise ConnectionRefusedError
|
raise ConnectionRefusedError
|
||||||
return user_pool
|
return user_pool
|
||||||
|
|
||||||
|
@ -94,9 +96,9 @@ class OpenNebulaManager():
|
||||||
|
|
||||||
except ConnectionRefusedError:
|
except ConnectionRefusedError:
|
||||||
logger.info('Could not connect to host: {host} via protocol {protocol}'.format(
|
logger.info('Could not connect to host: {host} via protocol {protocol}'.format(
|
||||||
host=settings.OPENNEBULA_DOMAIN,
|
host=settings.OPENNEBULA_DOMAIN,
|
||||||
protocol=settings.OPENNEBULA_PROTOCOL)
|
protocol=settings.OPENNEBULA_PROTOCOL)
|
||||||
)
|
)
|
||||||
raise ConnectionRefusedError
|
raise ConnectionRefusedError
|
||||||
# For now we'll just handle all other errors as connection errors
|
# For now we'll just handle all other errors as connection errors
|
||||||
except:
|
except:
|
||||||
|
@ -108,7 +110,6 @@ class OpenNebulaManager():
|
||||||
except ConnectionRefusedError:
|
except ConnectionRefusedError:
|
||||||
raise ConnectionRefusedError
|
raise ConnectionRefusedError
|
||||||
|
|
||||||
|
|
||||||
def get_vm(self, vm_id):
|
def get_vm(self, vm_id):
|
||||||
vm_id = int(vm_id)
|
vm_id = int(vm_id)
|
||||||
try:
|
try:
|
||||||
|
@ -118,7 +119,7 @@ class OpenNebulaManager():
|
||||||
raise ConnectionRefusedError
|
raise ConnectionRefusedError
|
||||||
|
|
||||||
def create_template(self, name, cores, memory, disk_size, core_price, memory_price,
|
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.
|
"""Create and add a new template to opennebula.
|
||||||
:param name: A string representation describing the template.
|
:param name: A string representation describing the template.
|
||||||
Used as label in view.
|
Used as label in view.
|
||||||
|
@ -136,11 +137,11 @@ class OpenNebulaManager():
|
||||||
template_string_formatter.format(
|
template_string_formatter.format(
|
||||||
name=name,
|
name=name,
|
||||||
vcpu=cores,
|
vcpu=cores,
|
||||||
cpu=0.1*cores,
|
cpu=0.1 * cores,
|
||||||
size=1024 * disk_size,
|
size=1024 * disk_size,
|
||||||
memory=1024 * memory,
|
memory=1024 * memory,
|
||||||
# * 10 because we set cpu to *0.1
|
# * 10 because we set cpu to *0.1
|
||||||
cpu_cost=10*core_price,
|
cpu_cost=10 * core_price,
|
||||||
memory_cost=memory_price,
|
memory_cost=memory_price,
|
||||||
disk_cost=disk_size_price,
|
disk_cost=disk_size_price,
|
||||||
ssh=ssh
|
ssh=ssh
|
||||||
|
@ -159,11 +160,11 @@ class OpenNebulaManager():
|
||||||
disk = template.template.disks[0]
|
disk = template.template.disks[0]
|
||||||
image_id = disk.image_id
|
image_id = disk.image_id
|
||||||
vm_specs = vm_specs_formatter.format(
|
vm_specs = vm_specs_formatter.format(
|
||||||
vcpu=int(specs['cpu']),
|
vcpu=int(specs['cpu']),
|
||||||
cpu=0.1* int(specs['cpu']),
|
cpu=0.1 * int(specs['cpu']),
|
||||||
memory=1024 * int(specs['memory']),
|
memory=1024 * int(specs['memory']),
|
||||||
|
|
||||||
)
|
)
|
||||||
vm_specs += """<DISK>
|
vm_specs += """<DISK>
|
||||||
<TYPE>fs</TYPE>
|
<TYPE>fs</TYPE>
|
||||||
<SIZE>{size}</SIZE>
|
<SIZE>{size}</SIZE>
|
||||||
|
@ -180,11 +181,11 @@ class OpenNebulaManager():
|
||||||
image_uname = disk.image_uname
|
image_uname = disk.image_uname
|
||||||
|
|
||||||
vm_specs = vm_specs_formatter.format(
|
vm_specs = vm_specs_formatter.format(
|
||||||
vcpu=int(specs['cpu']),
|
vcpu=int(specs['cpu']),
|
||||||
cpu=0.1* int(specs['cpu']),
|
cpu=0.1 * int(specs['cpu']),
|
||||||
memory=1024 * int(specs['memory']),
|
memory=1024 * int(specs['memory']),
|
||||||
|
|
||||||
)
|
)
|
||||||
vm_specs += """<DISK>
|
vm_specs += """<DISK>
|
||||||
<TYPE>fs</TYPE>
|
<TYPE>fs</TYPE>
|
||||||
<SIZE>{size}</SIZE>
|
<SIZE>{size}</SIZE>
|
||||||
|
@ -197,11 +198,11 @@ class OpenNebulaManager():
|
||||||
image=image,
|
image=image,
|
||||||
image_uname=image_uname)
|
image_uname=image_uname)
|
||||||
vm_id = self.client.call(oca.VmTemplate.METHODS['instantiate'],
|
vm_id = self.client.call(oca.VmTemplate.METHODS['instantiate'],
|
||||||
template.id,
|
template.id,
|
||||||
'',
|
'',
|
||||||
True,
|
True,
|
||||||
vm_specs,
|
vm_specs,
|
||||||
False)
|
False)
|
||||||
|
|
||||||
self.oneadmin_client.call(
|
self.oneadmin_client.call(
|
||||||
'vm.update',
|
'vm.update',
|
||||||
|
@ -219,13 +220,14 @@ class OpenNebulaManager():
|
||||||
self.opennebula_user.group_ids[0]
|
self.opennebula_user.group_ids[0]
|
||||||
)
|
)
|
||||||
except AttributeError:
|
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(
|
self.oneadmin_client.call(
|
||||||
oca.VirtualMachine.METHODS['action'],
|
oca.VirtualMachine.METHODS['action'],
|
||||||
'release',
|
'release',
|
||||||
vm_id
|
vm_id
|
||||||
)
|
)
|
||||||
return vm_id
|
return vm_id
|
||||||
|
|
||||||
def delete_vm(self, vm_id):
|
def delete_vm(self, vm_id):
|
||||||
|
@ -241,7 +243,8 @@ class OpenNebulaManager():
|
||||||
except socket.timeout as socket_err:
|
except socket.timeout as socket_err:
|
||||||
logger.info("Socket timeout error: {0}".format(socket_err))
|
logger.info("Socket timeout error: {0}".format(socket_err))
|
||||||
except OpenNebulaException as opennebula_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:
|
except OSError as os_err:
|
||||||
logger.info("OSError : {0}".format(os_err))
|
logger.info("OSError : {0}".format(os_err))
|
||||||
except ValueError as value_err:
|
except ValueError as value_err:
|
||||||
|
@ -251,26 +254,25 @@ class OpenNebulaManager():
|
||||||
|
|
||||||
def _get_template_pool(self):
|
def _get_template_pool(self):
|
||||||
try:
|
try:
|
||||||
template_pool = oca.VmTemplatePool(self.oneadmin_client)
|
template_pool = oca.VmTemplatePool(self.oneadmin_client)
|
||||||
template_pool.info()
|
template_pool.info()
|
||||||
return template_pool
|
return template_pool
|
||||||
except ConnectionRefusedError:
|
except ConnectionRefusedError:
|
||||||
logger.info('Could not connect to host: {host} via protocol {protocol}'.format(
|
logger.info('Could not connect to host: {host} via protocol {protocol}'.format(
|
||||||
host=settings.OPENNEBULA_DOMAIN,
|
host=settings.OPENNEBULA_DOMAIN,
|
||||||
protocol=settings.OPENNEBULA_PROTOCOL)
|
protocol=settings.OPENNEBULA_PROTOCOL)
|
||||||
)
|
)
|
||||||
raise ConnectionRefusedError
|
raise ConnectionRefusedError
|
||||||
except:
|
except:
|
||||||
raise ConnectionRefusedError
|
raise ConnectionRefusedError
|
||||||
|
|
||||||
|
|
||||||
def get_templates(self):
|
def get_templates(self):
|
||||||
try:
|
try:
|
||||||
public_templates = [
|
public_templates = [
|
||||||
template
|
template
|
||||||
for template in self._get_template_pool()
|
for template in self._get_template_pool()
|
||||||
if 'public-' in template.name
|
if 'public-' in template.name
|
||||||
]
|
]
|
||||||
return public_templates
|
return public_templates
|
||||||
except ConnectionRefusedError:
|
except ConnectionRefusedError:
|
||||||
raise ConnectionRefusedError
|
raise ConnectionRefusedError
|
||||||
|
@ -291,10 +293,8 @@ class OpenNebulaManager():
|
||||||
except:
|
except:
|
||||||
raise ConnectionRefusedError
|
raise ConnectionRefusedError
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def create_template(self, name, cores, memory, disk_size, core_price, memory_price,
|
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.
|
"""Create and add a new template to opennebula.
|
||||||
:param name: A string representation describing the template.
|
:param name: A string representation describing the template.
|
||||||
Used as label in view.
|
Used as label in view.
|
||||||
|
@ -327,11 +327,11 @@ class OpenNebulaManager():
|
||||||
template_string_formatter.format(
|
template_string_formatter.format(
|
||||||
name=name,
|
name=name,
|
||||||
vcpu=cores,
|
vcpu=cores,
|
||||||
cpu=0.1*cores,
|
cpu=0.1 * cores,
|
||||||
size=1024 * disk_size,
|
size=1024 * disk_size,
|
||||||
memory=1024 * memory,
|
memory=1024 * memory,
|
||||||
# * 10 because we set cpu to *0.1
|
# * 10 because we set cpu to *0.1
|
||||||
cpu_cost=10*core_price,
|
cpu_cost=10 * core_price,
|
||||||
memory_cost=memory_price,
|
memory_cost=memory_price,
|
||||||
disk_cost=disk_size_price,
|
disk_cost=disk_size_price,
|
||||||
ssh=ssh
|
ssh=ssh
|
||||||
|
@ -341,7 +341,8 @@ class OpenNebulaManager():
|
||||||
return template_id
|
return template_id
|
||||||
|
|
||||||
def delete_template(self, 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):
|
def change_user_password(self, new_password):
|
||||||
self.oneadmin_client.call(
|
self.oneadmin_client.call(
|
||||||
|
|
Loading…
Reference in a new issue