Merge branch 'task/5509/add-keys-to-opennebula-user' into 'master'
Save user's key in opennebula See merge request ungleich-public/dynamicweb!704
This commit is contained in:
commit
59a78dd8bb
10 changed files with 195 additions and 94 deletions
|
@ -186,3 +186,8 @@ footer .dcl-link-separator::before {
|
||||||
background: transparent !important;
|
background: transparent !important;
|
||||||
resize: none;
|
resize: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.existing-keys-title {
|
||||||
|
font-weight: bold;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
|
@ -8,7 +8,6 @@ from django.core.mail import EmailMessage
|
||||||
from django.core.urlresolvers import reverse
|
from django.core.urlresolvers import reverse
|
||||||
from django.utils import translation
|
from django.utils import translation
|
||||||
from django.utils.translation import ugettext_lazy as _
|
from django.utils.translation import ugettext_lazy as _
|
||||||
from time import sleep
|
|
||||||
|
|
||||||
from dynamicweb.celery import app
|
from dynamicweb.celery import app
|
||||||
from hosting.models import HostingOrder
|
from hosting.models import HostingOrder
|
||||||
|
@ -16,7 +15,7 @@ from membership.models import CustomUser
|
||||||
from opennebula_api.models import OpenNebulaManager
|
from opennebula_api.models import OpenNebulaManager
|
||||||
from opennebula_api.serializers import VirtualMachineSerializer
|
from opennebula_api.serializers import VirtualMachineSerializer
|
||||||
from utils.hosting_utils import (
|
from utils.hosting_utils import (
|
||||||
get_all_public_keys, get_or_create_vm_detail, ping_ok
|
get_all_public_keys, get_or_create_vm_detail
|
||||||
)
|
)
|
||||||
from utils.mailer import BaseEmail
|
from utils.mailer import BaseEmail
|
||||||
from utils.stripe_utils import StripeUtils
|
from utils.stripe_utils import StripeUtils
|
||||||
|
@ -79,10 +78,14 @@ def create_vm_task(self, vm_template_id, user, specs, template, order_id):
|
||||||
# Create OpenNebulaManager
|
# Create OpenNebulaManager
|
||||||
manager = OpenNebulaManager(email=on_user, password=on_pass)
|
manager = OpenNebulaManager(email=on_user, password=on_pass)
|
||||||
|
|
||||||
|
custom_user = CustomUser.objects.get(email=user.get('email'))
|
||||||
|
pub_keys = get_all_public_keys(custom_user)
|
||||||
|
if manager.email != settings.OPENNEBULA_USERNAME:
|
||||||
|
manager.save_key_in_opennebula_user('\n'.join(pub_keys))
|
||||||
vm_id = manager.create_vm(
|
vm_id = manager.create_vm(
|
||||||
template_id=vm_template_id,
|
template_id=vm_template_id,
|
||||||
specs=specs,
|
specs=specs,
|
||||||
ssh_key=settings.ONEADMIN_USER_SSH_PUBLIC_KEY,
|
ssh_key='\n'.join(pub_keys),
|
||||||
vm_name=vm_name
|
vm_name=vm_name
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -188,65 +191,9 @@ def create_vm_task(self, vm_template_id, user, specs, template, order_id):
|
||||||
email = BaseEmail(**email_data)
|
email = BaseEmail(**email_data)
|
||||||
email.send()
|
email.send()
|
||||||
|
|
||||||
# try to see if we have the IPv6 of the new vm and that if the ssh
|
|
||||||
# keys can be configured
|
|
||||||
vm_ipv6 = manager.get_ipv6(vm_id)
|
|
||||||
logger.debug("New VM ID is {vm_id}".format(vm_id=vm_id))
|
logger.debug("New VM ID is {vm_id}".format(vm_id=vm_id))
|
||||||
if vm_ipv6 is not None:
|
if vm_id > 0:
|
||||||
custom_user = CustomUser.objects.get(email=user.get('email'))
|
|
||||||
get_or_create_vm_detail(custom_user, manager, vm_id)
|
get_or_create_vm_detail(custom_user, manager, vm_id)
|
||||||
if custom_user is not None:
|
|
||||||
public_keys = get_all_public_keys(custom_user)
|
|
||||||
keys = [{'value': key, 'state': True} for key in
|
|
||||||
public_keys]
|
|
||||||
if len(keys) > 0:
|
|
||||||
logger.debug(
|
|
||||||
"Calling configure on {host} for "
|
|
||||||
"{num_keys} keys".format(
|
|
||||||
host=vm_ipv6, num_keys=len(keys)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
# Let's wait until the IP responds to ping before we
|
|
||||||
# run the cdist configure on the host
|
|
||||||
did_manage_public_key = False
|
|
||||||
for i in range(0, 15):
|
|
||||||
if ping_ok(vm_ipv6):
|
|
||||||
logger.debug(
|
|
||||||
"{} is pingable. Doing a "
|
|
||||||
"manage_public_key".format(vm_ipv6)
|
|
||||||
)
|
|
||||||
sleep(10)
|
|
||||||
manager.manage_public_key(
|
|
||||||
keys, hosts=[vm_ipv6]
|
|
||||||
)
|
|
||||||
did_manage_public_key = True
|
|
||||||
break
|
|
||||||
else:
|
|
||||||
logger.debug(
|
|
||||||
"Can't ping {}. Wait 5 secs".format(
|
|
||||||
vm_ipv6
|
|
||||||
)
|
|
||||||
)
|
|
||||||
sleep(5)
|
|
||||||
if not did_manage_public_key:
|
|
||||||
emsg = ("Waited for over 75 seconds for {} to be "
|
|
||||||
"pingable. But the VM was not reachable. "
|
|
||||||
"So, gave up manage_public_key. Please do "
|
|
||||||
"this manually".format(vm_ipv6))
|
|
||||||
logger.error(emsg)
|
|
||||||
email_data = {
|
|
||||||
'subject': '{} CELERY TASK INCOMPLETE: {} not '
|
|
||||||
'pingable for 75 seconds'.format(
|
|
||||||
settings.DCL_TEXT, vm_ipv6
|
|
||||||
),
|
|
||||||
'from_email': current_task.request.hostname,
|
|
||||||
'to': settings.DCL_ERROR_EMAILS_TO_LIST,
|
|
||||||
'body': emsg
|
|
||||||
}
|
|
||||||
email = EmailMessage(**email_data)
|
|
||||||
email.send()
|
|
||||||
else:
|
|
||||||
logger.debug("VM's ipv6 is None. Hence not created VMDetail")
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(str(e))
|
logger.error(str(e))
|
||||||
try:
|
try:
|
||||||
|
|
|
@ -134,6 +134,38 @@
|
||||||
</div>
|
</div>
|
||||||
<form id="virtual_machine_create_form" action="" method="POST">
|
<form id="virtual_machine_create_form" action="" method="POST">
|
||||||
{% csrf_token %}
|
{% csrf_token %}
|
||||||
|
{% if generic_payment_details %}
|
||||||
|
{% else %}
|
||||||
|
{% comment %}
|
||||||
|
We are in VM buy flow and we want user to click the "Place order" button.
|
||||||
|
At this point, we also want the user to input the SSH key for the VM.
|
||||||
|
{% endcomment %}
|
||||||
|
|
||||||
|
{% if messages %}
|
||||||
|
<div class="alert alert-warning">
|
||||||
|
{% for message in messages %}
|
||||||
|
<span>{{ message }}</span>
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
<div class="dashboard-container-head">
|
||||||
|
<h2 class="dashboard-title-thin"><i class="fa fa-key" aria-hidden="true"></i> {% trans "Add your public SSH key" %}</h2>
|
||||||
|
</div>
|
||||||
|
<div class="existing-keys">
|
||||||
|
{% if keys|length > 0 %}
|
||||||
|
<div class="existing-keys-title">Existing keys</div>
|
||||||
|
{% endif %}
|
||||||
|
{% for key in keys %}
|
||||||
|
<textarea class="form-control input-no-border" style="width: 100%" readonly rows="6">
|
||||||
|
{{key}}
|
||||||
|
</textarea>
|
||||||
|
<br/>
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
{% for field in form %}
|
||||||
|
{% bootstrap_field field %}
|
||||||
|
{% endfor %}
|
||||||
|
{% endif %}
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-sm-8">
|
<div class="col-sm-8">
|
||||||
{% if generic_payment_details %}
|
{% if generic_payment_details %}
|
||||||
|
|
|
@ -13,7 +13,8 @@ from django.views.decorators.cache import cache_control
|
||||||
from django.views.generic import FormView, CreateView, DetailView
|
from django.views.generic import FormView, CreateView, DetailView
|
||||||
|
|
||||||
from hosting.forms import (
|
from hosting.forms import (
|
||||||
HostingUserLoginForm, GenericPaymentForm, ProductPaymentForm
|
HostingUserLoginForm, GenericPaymentForm, ProductPaymentForm,
|
||||||
|
UserHostingKeyForm
|
||||||
)
|
)
|
||||||
from hosting.models import (
|
from hosting.models import (
|
||||||
HostingBill, HostingOrder, UserCardDetail, GenericProduct
|
HostingBill, HostingOrder, UserCardDetail, GenericProduct
|
||||||
|
@ -24,7 +25,7 @@ from utils.forms import (
|
||||||
BillingAddressForm, BillingAddressFormSignup, UserBillingAddressForm,
|
BillingAddressForm, BillingAddressFormSignup, UserBillingAddressForm,
|
||||||
BillingAddress
|
BillingAddress
|
||||||
)
|
)
|
||||||
from utils.hosting_utils import get_vm_price_with_vat
|
from utils.hosting_utils import get_vm_price_with_vat, get_all_public_keys
|
||||||
from utils.stripe_utils import StripeUtils
|
from utils.stripe_utils import StripeUtils
|
||||||
from utils.tasks import send_plain_email_task
|
from utils.tasks import send_plain_email_task
|
||||||
from .cms_models import DCLCalculatorPluginModel
|
from .cms_models import DCLCalculatorPluginModel
|
||||||
|
@ -529,12 +530,18 @@ class PaymentOrderView(FormView):
|
||||||
return self.render_to_response(context)
|
return self.render_to_response(context)
|
||||||
|
|
||||||
|
|
||||||
class OrderConfirmationView(DetailView):
|
class OrderConfirmationView(DetailView, FormView):
|
||||||
|
form_class = UserHostingKeyForm
|
||||||
template_name = "datacenterlight/order_detail.html"
|
template_name = "datacenterlight/order_detail.html"
|
||||||
payment_template_name = 'datacenterlight/landing_payment.html'
|
payment_template_name = 'datacenterlight/landing_payment.html'
|
||||||
context_object_name = "order"
|
context_object_name = "order"
|
||||||
model = HostingOrder
|
model = HostingOrder
|
||||||
|
|
||||||
|
def get_form_kwargs(self):
|
||||||
|
kwargs = super(OrderConfirmationView, self).get_form_kwargs()
|
||||||
|
kwargs.update({'request': self.request})
|
||||||
|
return kwargs
|
||||||
|
|
||||||
@cache_control(no_cache=True, must_revalidate=True, no_store=True)
|
@cache_control(no_cache=True, must_revalidate=True, no_store=True)
|
||||||
def get(self, request, *args, **kwargs):
|
def get(self, request, *args, **kwargs):
|
||||||
context = {}
|
context = {}
|
||||||
|
@ -567,6 +574,8 @@ class OrderConfirmationView(DetailView):
|
||||||
else:
|
else:
|
||||||
context.update({
|
context.update({
|
||||||
'vm': request.session.get('specs'),
|
'vm': request.session.get('specs'),
|
||||||
|
'form': UserHostingKeyForm(request=self.request),
|
||||||
|
'keys': get_all_public_keys(self.request.user)
|
||||||
})
|
})
|
||||||
context.update({
|
context.update({
|
||||||
'site_url': reverse('datacenterlight:index'),
|
'site_url': reverse('datacenterlight:index'),
|
||||||
|
@ -579,6 +588,31 @@ class OrderConfirmationView(DetailView):
|
||||||
return render(request, self.template_name, context)
|
return render(request, self.template_name, context)
|
||||||
|
|
||||||
def post(self, request, *args, **kwargs):
|
def post(self, request, *args, **kwargs):
|
||||||
|
# Check ssh public key and then proceed
|
||||||
|
form = self.get_form()
|
||||||
|
required = True
|
||||||
|
|
||||||
|
# SSH key validation is required only if the user doesn't have an
|
||||||
|
# existing key and user has input some value in the add ssh key fields
|
||||||
|
if (len(get_all_public_keys(self.request.user)) > 0 and
|
||||||
|
(len(form.data.get('public_key')) == 0 and
|
||||||
|
len(form.data.get('name')) == 0)):
|
||||||
|
required = False
|
||||||
|
form.fields['name'].required = required
|
||||||
|
form.fields['public_key'].required = required
|
||||||
|
if not form.is_valid():
|
||||||
|
response = {
|
||||||
|
'status': False,
|
||||||
|
'msg_title': str(_('SSH key related error occurred')),
|
||||||
|
'msg_body': "<br/>".join([str(v) for k,v in form.errors.items()]),
|
||||||
|
}
|
||||||
|
return JsonResponse(response)
|
||||||
|
|
||||||
|
if required:
|
||||||
|
# We have a valid SSH key from the user, save it in opennebula and
|
||||||
|
# db and proceed further
|
||||||
|
form.save()
|
||||||
|
|
||||||
user = request.session.get('user')
|
user = request.session.get('user')
|
||||||
stripe_api_cus_id = request.session.get('customer')
|
stripe_api_cus_id = request.session.get('customer')
|
||||||
stripe_utils = StripeUtils()
|
stripe_utils = StripeUtils()
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
import datetime
|
import datetime
|
||||||
import logging
|
import logging
|
||||||
import subprocess
|
import subprocess
|
||||||
|
|
||||||
import tempfile
|
import tempfile
|
||||||
|
|
||||||
from django import forms
|
from django import forms
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.contrib.auth import authenticate
|
from django.contrib.auth import authenticate
|
||||||
|
@ -187,7 +187,8 @@ class UserHostingKeyForm(forms.ModelForm):
|
||||||
alerts the user of it.
|
alerts the user of it.
|
||||||
:return:
|
:return:
|
||||||
"""
|
"""
|
||||||
if 'generate' in self.request.POST:
|
if ('generate' in self.request.POST
|
||||||
|
or not self.fields['public_key'].required):
|
||||||
return self.data.get('public_key')
|
return self.data.get('public_key')
|
||||||
KEY_ERROR_MESSAGE = _("Please input a proper SSH key")
|
KEY_ERROR_MESSAGE = _("Please input a proper SSH key")
|
||||||
openssh_pubkey_str = self.data.get('public_key').strip()
|
openssh_pubkey_str = self.data.get('public_key').strip()
|
||||||
|
@ -214,6 +215,10 @@ class UserHostingKeyForm(forms.ModelForm):
|
||||||
return openssh_pubkey_str
|
return openssh_pubkey_str
|
||||||
|
|
||||||
def clean_name(self):
|
def clean_name(self):
|
||||||
|
INVALID_NAME_MESSAGE = _("Comma not accepted in the name of the key")
|
||||||
|
if "," in self.data.get('name'):
|
||||||
|
logger.debug(INVALID_NAME_MESSAGE)
|
||||||
|
raise forms.ValidationError(INVALID_NAME_MESSAGE)
|
||||||
return self.data.get('name')
|
return self.data.get('name')
|
||||||
|
|
||||||
def clean_user(self):
|
def clean_user(self):
|
||||||
|
|
|
@ -109,8 +109,11 @@ $(document).ready(function() {
|
||||||
modal_btn = $('#createvm-modal-done-btn');
|
modal_btn = $('#createvm-modal-done-btn');
|
||||||
$('#createvm-modal-title').text(data.msg_title);
|
$('#createvm-modal-title').text(data.msg_title);
|
||||||
$('#createvm-modal-body').html(data.msg_body);
|
$('#createvm-modal-body').html(data.msg_body);
|
||||||
modal_btn.attr('href', data.redirect)
|
if (data.redirect) {
|
||||||
.removeClass('hide');
|
modal_btn.attr('href', data.redirect).removeClass('hide');
|
||||||
|
} else {
|
||||||
|
modal_btn.attr('href', "");
|
||||||
|
}
|
||||||
if (data.status === true) {
|
if (data.status === true) {
|
||||||
fa_icon.attr('class', 'checkmark');
|
fa_icon.attr('class', 'checkmark');
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -198,6 +198,35 @@
|
||||||
{% block submit_btn %}
|
{% block submit_btn %}
|
||||||
<form method="post" id="virtual_machine_create_form">
|
<form method="post" id="virtual_machine_create_form">
|
||||||
{% csrf_token %}
|
{% csrf_token %}
|
||||||
|
{% comment %}
|
||||||
|
We are in VM buy flow and we want user to click the "Place order" button.
|
||||||
|
At this point, we also want the user to input the SSH key for the VM.
|
||||||
|
{% endcomment %}
|
||||||
|
|
||||||
|
{% if messages %}
|
||||||
|
<div class="alert alert-warning">
|
||||||
|
{% for message in messages %}
|
||||||
|
<span>{{ message }}</span>
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
<div class="dashboard-container-head">
|
||||||
|
<h2 class="dashboard-title-thin"><i class="fa fa-key" aria-hidden="true"></i> {% trans "Add your public SSH key" %}</h2>
|
||||||
|
</div>
|
||||||
|
<div class="existing-keys">
|
||||||
|
{% if keys|length > 0 %}
|
||||||
|
<div class="existing-keys-title">Existing keys</div>
|
||||||
|
{% endif %}
|
||||||
|
{% for key in keys %}
|
||||||
|
<textarea class="form-control input-no-border" style="width: 100%" readonly rows="6">
|
||||||
|
{{key}}
|
||||||
|
</textarea>
|
||||||
|
<br/>
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
{% for field in form %}
|
||||||
|
{% bootstrap_field field %}
|
||||||
|
{% endfor %}
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-sm-8">
|
<div class="col-sm-8">
|
||||||
<div class="dcl-place-order-text">{% blocktrans with vm_price=vm.total_price|floatformat:2|intcomma %}By clicking "Place order" this plan will charge your credit card account with {{ vm_price }} CHF/month{% endblocktrans %}.</div>
|
<div class="dcl-place-order-text">{% blocktrans with vm_price=vm.total_price|floatformat:2|intcomma %}By clicking "Place order" this plan will charge your credit card account with {{ vm_price }} CHF/month{% endblocktrans %}.</div>
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
from django.conf.urls import url
|
from django.conf.urls import url
|
||||||
from django.contrib.auth import views as auth_views
|
from django.contrib.auth import views as auth_views
|
||||||
|
|
||||||
from .views import (
|
from .views import (
|
||||||
DjangoHostingView, RailsHostingView, PaymentVMView, NodeJSHostingView,
|
DjangoHostingView, RailsHostingView, PaymentVMView, NodeJSHostingView,
|
||||||
LoginView, SignupView, SignupValidateView, SignupValidatedView, IndexView,
|
LoginView, SignupView, SignupValidateView, SignupValidatedView, IndexView,
|
||||||
|
@ -12,7 +13,6 @@ from .views import (
|
||||||
InvoiceListView, InvoiceDetailView, CheckUserVM
|
InvoiceListView, InvoiceDetailView, CheckUserVM
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
url(r'index/?$', IndexView.as_view(), name='index'),
|
url(r'index/?$', IndexView.as_view(), name='index'),
|
||||||
url(r'django/?$', DjangoHostingView.as_view(), name='djangohosting'),
|
url(r'django/?$', DjangoHostingView.as_view(), name='djangohosting'),
|
||||||
|
|
|
@ -49,6 +49,7 @@ from utils.forms import (
|
||||||
BillingAddressForm, PasswordResetRequestForm, UserBillingAddressForm,
|
BillingAddressForm, PasswordResetRequestForm, UserBillingAddressForm,
|
||||||
ResendActivationEmailForm
|
ResendActivationEmailForm
|
||||||
)
|
)
|
||||||
|
from utils.hosting_utils import get_all_public_keys
|
||||||
from utils.hosting_utils import get_vm_price_with_vat, HostingUtils
|
from utils.hosting_utils import get_vm_price_with_vat, HostingUtils
|
||||||
from utils.mailer import BaseEmail
|
from utils.mailer import BaseEmail
|
||||||
from utils.stripe_utils import StripeUtils
|
from utils.stripe_utils import StripeUtils
|
||||||
|
@ -466,7 +467,9 @@ class SSHKeyDeleteView(LoginRequiredMixin, DeleteView):
|
||||||
pk = self.kwargs.get('pk')
|
pk = self.kwargs.get('pk')
|
||||||
# Get user ssh key
|
# Get user ssh key
|
||||||
public_key = UserHostingKey.objects.get(pk=pk).public_key
|
public_key = UserHostingKey.objects.get(pk=pk).public_key
|
||||||
manager.manage_public_key([{'value': public_key, 'state': False}])
|
keys = UserHostingKey.objects.filter(user=self.request.user)
|
||||||
|
keys_to_save = [k.public_key for k in keys if k.public_key != public_key]
|
||||||
|
manager.save_key_in_opennebula_user('\n'.join(keys_to_save), update_type=0)
|
||||||
|
|
||||||
return super(SSHKeyDeleteView, self).delete(request, *args, **kwargs)
|
return super(SSHKeyDeleteView, self).delete(request, *args, **kwargs)
|
||||||
|
|
||||||
|
@ -515,8 +518,8 @@ class SSHKeyChoiceView(LoginRequiredMixin, View):
|
||||||
email=owner.email,
|
email=owner.email,
|
||||||
password=owner.password
|
password=owner.password
|
||||||
)
|
)
|
||||||
public_key_str = public_key.decode()
|
keys = get_all_public_keys(request.user)
|
||||||
manager.manage_public_key([{'value': public_key_str, 'state': True}])
|
manager.save_key_in_opennebula_user('\n'.join(keys))
|
||||||
return redirect(reverse_lazy('hosting:ssh_keys'), foo='bar')
|
return redirect(reverse_lazy('hosting:ssh_keys'), foo='bar')
|
||||||
|
|
||||||
|
|
||||||
|
@ -566,10 +569,8 @@ class SSHKeyCreateView(LoginRequiredMixin, FormView):
|
||||||
email=owner.email,
|
email=owner.email,
|
||||||
password=owner.password
|
password=owner.password
|
||||||
)
|
)
|
||||||
public_key = form.cleaned_data['public_key']
|
keys_to_save = get_all_public_keys(self.request.user)
|
||||||
if type(public_key) is bytes:
|
manager.save_key_in_opennebula_user('\n'.join(keys_to_save))
|
||||||
public_key = public_key.decode()
|
|
||||||
manager.manage_public_key([{'value': public_key, 'state': True}])
|
|
||||||
return HttpResponseRedirect(self.success_url)
|
return HttpResponseRedirect(self.success_url)
|
||||||
|
|
||||||
def post(self, request, *args, **kwargs):
|
def post(self, request, *args, **kwargs):
|
||||||
|
@ -837,13 +838,19 @@ class PaymentVMView(LoginRequiredMixin, FormView):
|
||||||
return self.form_invalid(form)
|
return self.form_invalid(form)
|
||||||
|
|
||||||
|
|
||||||
class OrdersHostingDetailView(LoginRequiredMixin, DetailView):
|
class OrdersHostingDetailView(LoginRequiredMixin, DetailView, FormView):
|
||||||
|
form_class = UserHostingKeyForm
|
||||||
template_name = "hosting/order_detail.html"
|
template_name = "hosting/order_detail.html"
|
||||||
context_object_name = "order"
|
context_object_name = "order"
|
||||||
login_url = reverse_lazy('hosting:login')
|
login_url = reverse_lazy('hosting:login')
|
||||||
permission_required = ['view_hostingorder']
|
permission_required = ['view_hostingorder']
|
||||||
model = HostingOrder
|
model = HostingOrder
|
||||||
|
|
||||||
|
def get_form_kwargs(self):
|
||||||
|
kwargs = super(OrdersHostingDetailView, self).get_form_kwargs()
|
||||||
|
kwargs.update({'request': self.request})
|
||||||
|
return kwargs
|
||||||
|
|
||||||
def get_object(self, queryset=None):
|
def get_object(self, queryset=None):
|
||||||
order_id = self.kwargs.get('pk')
|
order_id = self.kwargs.get('pk')
|
||||||
try:
|
try:
|
||||||
|
@ -868,6 +875,8 @@ class OrdersHostingDetailView(LoginRequiredMixin, DetailView):
|
||||||
|
|
||||||
if self.request.GET.get('page') == 'payment':
|
if self.request.GET.get('page') == 'payment':
|
||||||
context['page_header_text'] = _('Confirm Order')
|
context['page_header_text'] = _('Confirm Order')
|
||||||
|
context['form'] = UserHostingKeyForm(request=self.request)
|
||||||
|
context['keys'] = get_all_public_keys(self.request.user)
|
||||||
else:
|
else:
|
||||||
context['page_header_text'] = _('Invoice')
|
context['page_header_text'] = _('Invoice')
|
||||||
if not self.request.user.has_perm(
|
if not self.request.user.has_perm(
|
||||||
|
@ -993,6 +1002,31 @@ class OrdersHostingDetailView(LoginRequiredMixin, DetailView):
|
||||||
|
|
||||||
@method_decorator(decorators)
|
@method_decorator(decorators)
|
||||||
def post(self, request):
|
def post(self, request):
|
||||||
|
# Check ssh public key and then proceed
|
||||||
|
form = self.get_form()
|
||||||
|
required = True
|
||||||
|
|
||||||
|
# SSH key validation is required only if the user doesn't have an
|
||||||
|
# existing key and user has input some value in the add ssh key fields
|
||||||
|
if (len(get_all_public_keys(self.request.user)) > 0 and
|
||||||
|
(len(form.data.get('public_key')) == 0 and
|
||||||
|
len(form.data.get('name')) == 0)):
|
||||||
|
required = False
|
||||||
|
form.fields['name'].required = required
|
||||||
|
form.fields['public_key'].required = required
|
||||||
|
if not form.is_valid():
|
||||||
|
response = {
|
||||||
|
'status': False,
|
||||||
|
'msg_title': str(_('SSH key related error occurred')),
|
||||||
|
'msg_body': "<br/>".join([str(v) for k,v in form.errors.items()]),
|
||||||
|
}
|
||||||
|
return JsonResponse(response)
|
||||||
|
|
||||||
|
if required:
|
||||||
|
# We have a valid SSH key from the user, save it in opennebula and
|
||||||
|
# db and proceed further
|
||||||
|
form.save()
|
||||||
|
|
||||||
template = request.session.get('template')
|
template = request.session.get('template')
|
||||||
specs = request.session.get('specs')
|
specs = request.session.get('specs')
|
||||||
stripe_utils = StripeUtils()
|
stripe_utils = StripeUtils()
|
||||||
|
@ -1573,7 +1607,8 @@ class VirtualMachineView(LoginRequiredMixin, View):
|
||||||
'virtual_machine': serializer.data,
|
'virtual_machine': serializer.data,
|
||||||
'order': HostingOrder.objects.get(
|
'order': HostingOrder.objects.get(
|
||||||
vm_id=serializer.data['vm_id']
|
vm_id=serializer.data['vm_id']
|
||||||
)
|
),
|
||||||
|
'keys': UserHostingKey.objects.filter(user=request.user)
|
||||||
}
|
}
|
||||||
except Exception as ex:
|
except Exception as ex:
|
||||||
logger.debug("Exception generated {}".format(str(ex)))
|
logger.debug("Exception generated {}".format(str(ex)))
|
||||||
|
@ -1639,7 +1674,7 @@ class VirtualMachineView(LoginRequiredMixin, View):
|
||||||
"manager.delete_vm returned False. Hence, error making "
|
"manager.delete_vm returned False. Hence, error making "
|
||||||
"xml-rpc call to delete vm failed."
|
"xml-rpc call to delete vm failed."
|
||||||
)
|
)
|
||||||
response['text'] = ugettext('Error terminating VM') + vm.id
|
response['text'] = str(_('Error terminating VM')) + str(vm.id)
|
||||||
else:
|
else:
|
||||||
for t in range(15):
|
for t in range(15):
|
||||||
try:
|
try:
|
||||||
|
|
|
@ -207,22 +207,8 @@ class OpenNebulaManager():
|
||||||
else:
|
else:
|
||||||
vm_pool.info()
|
vm_pool.info()
|
||||||
return vm_pool
|
return vm_pool
|
||||||
except AttributeError:
|
except AttributeError as ae:
|
||||||
logger.error(
|
logger.error("AttributeError : %s" % str(ae))
|
||||||
'Could not connect via client, using oneadmin instead')
|
|
||||||
try:
|
|
||||||
vm_pool = oca.VirtualMachinePool(self.oneadmin_client)
|
|
||||||
if infoextended:
|
|
||||||
vm_pool.infoextended(
|
|
||||||
filter=-1, # User's resources and any of his groups
|
|
||||||
vm_state=-1 # Look for VMs in any state, except DONE
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
vm_pool.info(filter=-2)
|
|
||||||
return vm_pool
|
|
||||||
except:
|
|
||||||
raise ConnectionRefusedError
|
|
||||||
|
|
||||||
except ConnectionRefusedError:
|
except ConnectionRefusedError:
|
||||||
logger.error(
|
logger.error(
|
||||||
'Could not connect to host: {host} via protocol {protocol}'.format(
|
'Could not connect to host: {host} via protocol {protocol}'.format(
|
||||||
|
@ -377,6 +363,31 @@ class OpenNebulaManager():
|
||||||
|
|
||||||
return vm_terminated
|
return vm_terminated
|
||||||
|
|
||||||
|
def save_key_in_opennebula_user(self, ssh_key, update_type=1):
|
||||||
|
"""
|
||||||
|
Save the given ssh key in OpenNebula user
|
||||||
|
|
||||||
|
# Update type: 0: Replace the whole template.
|
||||||
|
1: Merge new template with the existing one.
|
||||||
|
:param ssh_key: The ssh key to be saved
|
||||||
|
:param update_type: The update type as explained above
|
||||||
|
|
||||||
|
:return:
|
||||||
|
"""
|
||||||
|
return_value = self.oneadmin_client.call(
|
||||||
|
'user.update',
|
||||||
|
self.opennebula_user.id,
|
||||||
|
'<CONTEXT><SSH_PUBLIC_KEY>%s</SSH_PUBLIC_KEY></CONTEXT>' % ssh_key,
|
||||||
|
update_type
|
||||||
|
)
|
||||||
|
if type(return_value) == int:
|
||||||
|
logger.debug(
|
||||||
|
"Saved the key in opennebula successfully : %s" % return_value)
|
||||||
|
else:
|
||||||
|
logger.error(
|
||||||
|
"Could not save the key in opennebula. %s" % return_value)
|
||||||
|
return
|
||||||
|
|
||||||
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)
|
||||||
|
|
Loading…
Reference in a new issue