merge master

This commit is contained in:
Arvind Tiwari 2017-09-15 00:19:01 +05:30
commit 8402fd4fd3
10 changed files with 386 additions and 79 deletions

View file

@ -1,16 +1,22 @@
import datetime
import logging
import subprocess
import tempfile
from django import forms
from membership.models import CustomUser
from django.contrib.auth import authenticate
from django.utils.translation import ugettext_lazy as _
from membership.models import CustomUser
from utils.hosting_utils import get_all_public_keys
from .models import UserHostingKey
logger = logging.getLogger(__name__)
def generate_ssh_key_name():
return 'dcl-generated-key-' + datetime.datetime.now().strftime('%m%d%y%H%M')
return 'dcl-generated-key-' + datetime.datetime.now().strftime(
'%m%d%y%H%M')
class HostingUserLoginForm(forms.Form):
@ -38,9 +44,7 @@ class HostingUserLoginForm(forms.Form):
CustomUser.objects.get(email=email)
return email
except CustomUser.DoesNotExist:
raise forms.ValidationError("User does not exist")
else:
return email
raise forms.ValidationError(_("User does not exist"))
class HostingUserSignupForm(forms.ModelForm):
@ -51,7 +55,8 @@ class HostingUserSignupForm(forms.ModelForm):
model = CustomUser
fields = ['name', 'email', 'password']
widgets = {
'name': forms.TextInput(attrs={'placeholder': 'Enter your name or company name'}),
'name': forms.TextInput(
attrs={'placeholder': 'Enter your name or company name'}),
}
def clean_confirm_password(self):
@ -65,19 +70,55 @@ class HostingUserSignupForm(forms.ModelForm):
class UserHostingKeyForm(forms.ModelForm):
private_key = forms.CharField(widget=forms.HiddenInput(), required=False)
public_key = forms.CharField(widget=forms.Textarea(
attrs={'class': 'form_public_key', 'placeholder': _('Paste here your public key')}),
attrs={'class': 'form_public_key',
'placeholder': _('Paste here your public key')}),
required=False,
)
user = forms.models.ModelChoiceField(queryset=CustomUser.objects.all(),
required=False, widget=forms.HiddenInput())
required=False,
widget=forms.HiddenInput())
name = forms.CharField(required=False, widget=forms.TextInput(
attrs={'class': 'form_key_name', 'placeholder': _('Give a name to your key')}))
attrs={'class': 'form_key_name',
'placeholder': _('Give a name to your key')}))
def __init__(self, *args, **kwargs):
self.request = kwargs.pop("request")
super(UserHostingKeyForm, self).__init__(*args, **kwargs)
self.fields['name'].label = _('Key name')
def clean_public_key(self):
"""
Validates a public ssh key using `ssh-keygen -lf key.pub`
Also checks if a given key already exists in the database and
alerts the user of it.
:return:
"""
if 'generate' in self.request.POST:
return self.data.get('public_key')
KEY_ERROR_MESSAGE = _("Please input a proper SSH key")
openssh_pubkey_str = self.data.get('public_key').strip()
if openssh_pubkey_str in get_all_public_keys(self.request.user):
key_name = UserHostingKey.objects.filter(
user_id=self.request.user.id,
public_key=openssh_pubkey_str).first().name
KEY_EXISTS_MESSAGE = _(
"This key exists already with the name \"%(name)s\"") % {
'name': key_name}
raise forms.ValidationError(KEY_EXISTS_MESSAGE)
with tempfile.NamedTemporaryFile(delete=True) as tmp_public_key_file:
tmp_public_key_file.write(openssh_pubkey_str.encode('utf-8'))
tmp_public_key_file.flush()
try:
subprocess.check_output(
['ssh-keygen', '-lf', tmp_public_key_file.name])
except subprocess.CalledProcessError as cpe:
logger.debug(
"Not a correct ssh format {error}".format(error=str(cpe)))
raise forms.ValidationError(KEY_ERROR_MESSAGE)
return openssh_pubkey_str
def clean_name(self):
return self.data.get('name')

View file

@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2017-09-14 02:55+0530\n"
"POT-Creation-Date: 2017-09-14 12:27+0000\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@ -24,6 +24,9 @@ msgstr "Dein Benutzername und/oder Dein Passwort ist falsch."
msgid "Your account is not activated yet."
msgstr "Dein Account wurde noch nicht aktiviert."
msgid "User does not exist"
msgstr "Der Benutzer existiert nicht"
msgid "Paste here your public key"
msgstr "Füge deinen Public Key ein"
@ -33,6 +36,13 @@ msgstr "Gebe deinem SSH-Key einen Name"
msgid "Key name"
msgstr "Key-Name"
msgid "Please input a proper SSH key"
msgstr "Bitte verwende einen gültigen SSH-Key"
#, python-format
msgid "This key exists already with the name \"%(name)s\""
msgstr "Der SSH-Key mit dem Name \"%(name)s\" existiert bereits"
msgid "All Rights Reserved"
msgstr "Alle Rechte vorbehalten"

View file

@ -1,3 +1,4 @@
import logging
import uuid
import json
from time import sleep
@ -18,7 +19,7 @@ from django.views.generic import View, CreateView, FormView, ListView, \
DetailView, \
DeleteView, TemplateView, UpdateView
from guardian.mixins import PermissionRequiredMixin
from oca.pool import WrongNameError, WrongIdError
from oca.pool import WrongIdError
from stored_messages.api import mark_read
from stored_messages.models import Message
from stored_messages.settings import stored_messages_settings
@ -29,6 +30,7 @@ from opennebula_api.serializers import VirtualMachineSerializer, \
VirtualMachineTemplateSerializer
from utils.forms import BillingAddressForm, PasswordResetRequestForm, \
UserBillingAddressForm
from utils.hosting_utils import get_all_public_keys
from utils.mailer import BaseEmail
from utils.stripe_utils import StripeUtils
from utils.views import PasswordResetViewMixin, PasswordResetConfirmViewMixin, \
@ -38,8 +40,11 @@ from .forms import HostingUserSignupForm, HostingUserLoginForm, \
from .mixins import ProcessVMSelectionMixin
from .models import HostingOrder, HostingBill, HostingPlan, UserHostingKey
CONNECTION_ERROR = "Your VMs cannot be displayed at the moment due to a backend \
connection error. please try again in a few minutes."
logger = logging.getLogger(__name__)
CONNECTION_ERROR = "Your VMs cannot be displayed at the moment due to a \
backend connection error. please try again in a few \
minutes."
class DashboardView(View):
@ -370,17 +375,14 @@ class SSHKeyDeleteView(LoginRequiredMixin, DeleteView):
def delete(self, request, *args, **kwargs):
owner = self.request.user
manager = OpenNebulaManager()
manager = OpenNebulaManager(
email=owner.email,
password=owner.password
)
pk = self.kwargs.get('pk')
# Get user ssh key
public_key = UserHostingKey.objects.get(pk=pk).public_key
# Add ssh key to user
try:
manager.remove_public_key(user=owner, public_key=public_key)
except ConnectionError:
pass
except WrongNameError:
pass
manager.manage_public_key([{'value': public_key, 'state': False}])
return super(SSHKeyDeleteView, self).delete(request, *args, **kwargs)
@ -421,6 +423,13 @@ class SSHKeyChoiceView(LoginRequiredMixin, View):
user=request.user, public_key=public_key, name=name)
filename = name + '_' + str(uuid.uuid4())[:8] + '_private.pem'
ssh_key.private_key.save(filename, content)
owner = self.request.user
manager = OpenNebulaManager(
email=owner.email,
password=owner.password
)
public_key_str = public_key.decode()
manager.manage_public_key([{'value': public_key_str, 'state': True}])
return redirect(reverse_lazy('hosting:ssh_keys'), foo='bar')
@ -465,23 +474,17 @@ class SSHKeyCreateView(LoginRequiredMixin, FormView):
})
owner = self.request.user
manager = OpenNebulaManager()
# Get user ssh key
public_key = str(form.cleaned_data.get('public_key', ''))
# Add ssh key to user
try:
manager.add_public_key(
user=owner, public_key=public_key, merge=True)
except ConnectionError:
pass
except WrongNameError:
pass
manager = OpenNebulaManager(
email=owner.email,
password=owner.password
)
public_key = form.cleaned_data['public_key']
if type(public_key) is bytes:
public_key = public_key.decode()
manager.manage_public_key([{'value': public_key, 'state': True}])
return HttpResponseRedirect(self.success_url)
def post(self, request, *args, **kwargs):
print(self.request.POST.dict())
form = self.get_form()
required = 'add_ssh' in self.request.POST
form.fields['name'].required = required
@ -662,16 +665,12 @@ class PaymentVMView(LoginRequiredMixin, FormView):
'form': form
})
return render(request, self.template_name, context)
# For now just get first one
user_key = UserHostingKey.objects.filter(
user=self.request.user).first()
# Create a vm using logged user
vm_id = manager.create_vm(
template_id=vm_template_id,
# XXX: Confi
specs=specs,
ssh_key=user_key.public_key,
ssh_key=settings.ONEADMIN_USER_SSH_PUBLIC_KEY,
)
# Create a Hosting Order
@ -725,6 +724,19 @@ class PaymentVMView(LoginRequiredMixin, FormView):
email = BaseEmail(**email_data)
email.send()
# try to see if we have the IP and that if the ssh keys can
# be configured
new_host = manager.get_primary_ipv4(vm_id)
if new_host is not None:
public_keys = get_all_public_keys(owner)
keys = [{'value': key, 'state': True} for key in public_keys]
logger.debug(
"Calling configure on {host} for {num_keys} keys".format(
host=new_host, num_keys=len(keys)))
# Let's delay the task by 75 seconds to be sure that we run
# the cdist configure after the host is up
manager.manage_public_key(keys, hosts=[new_host], countdown=75)
return HttpResponseRedirect(
"{url}?{query_params}".format(
url=reverse('hosting:orders', kwargs={'pk': order.id}),
@ -919,7 +931,8 @@ class VirtualMachineView(LoginRequiredMixin, View):
'order': HostingOrder.objects.get(
vm_id=serializer.data['vm_id'])
}
except:
except Exception as ex:
logger.debug("Exception generated {}".format(str(ex)))
pass
return render(request, self.template_name, context)