Merge branch 'develop' into api/cleanup
This commit is contained in:
commit
d229d124e9
7 changed files with 119 additions and 48 deletions
|
@ -4,6 +4,7 @@ from django import forms
|
||||||
from membership.models import CustomUser
|
from membership.models import CustomUser
|
||||||
from django.contrib.auth import authenticate
|
from django.contrib.auth import authenticate
|
||||||
|
|
||||||
|
from django.utils.translation import ugettext_lazy as _
|
||||||
|
|
||||||
from utils.stripe_utils import StripeUtils
|
from utils.stripe_utils import StripeUtils
|
||||||
|
|
||||||
|
@ -57,10 +58,12 @@ class HostingUserSignupForm(forms.ModelForm):
|
||||||
|
|
||||||
|
|
||||||
class UserHostingKeyForm(forms.ModelForm):
|
class UserHostingKeyForm(forms.ModelForm):
|
||||||
private_key = forms.CharField(widget=forms.PasswordInput(), required=False)
|
private_key = forms.CharField(widget=forms.HiddenInput(), required=False)
|
||||||
public_key = forms.CharField(widget=forms.PasswordInput(), required=False)
|
public_key = forms.CharField(widget=forms.Textarea(), required=False,
|
||||||
user = forms.models.ModelChoiceField(queryset=CustomUser.objects.all(), required=False)
|
help_text=_('Paste here your public key'))
|
||||||
name = forms.CharField(required=False)
|
user = forms.models.ModelChoiceField(queryset=CustomUser.objects.all(),
|
||||||
|
required=False, widget=forms.HiddenInput())
|
||||||
|
name = forms.CharField(required=True)
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
self.request = kwargs.pop("request")
|
self.request = kwargs.pop("request")
|
||||||
|
@ -69,9 +72,7 @@ class UserHostingKeyForm(forms.ModelForm):
|
||||||
# print(self.fields)
|
# print(self.fields)
|
||||||
|
|
||||||
def clean_name(self):
|
def clean_name(self):
|
||||||
return "dcl-priv-key-%s" % (
|
return self.data.get('name')
|
||||||
''.join(random.choice(string.ascii_lowercase) for i in range(7))
|
|
||||||
)
|
|
||||||
|
|
||||||
def clean_user(self):
|
def clean_user(self):
|
||||||
return self.request.user
|
return self.request.user
|
||||||
|
@ -90,4 +91,15 @@ class UserHostingKeyForm(forms.ModelForm):
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = UserHostingKey
|
model = UserHostingKey
|
||||||
fields = ['user', 'public_key', 'name']
|
fields = ['user', 'name', 'public_key']
|
||||||
|
labels = {
|
||||||
|
'public_key': _('Writer'),
|
||||||
|
}
|
||||||
|
help_texts = {
|
||||||
|
'public_key': 'Put your shit here',
|
||||||
|
}
|
||||||
|
error_messages = {
|
||||||
|
'name': {
|
||||||
|
'max_length': _("This writer's name is too long."),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-md-9 col-md-offset-2">
|
<div class="col-md-9 col-md-offset-2">
|
||||||
<div class="col-sm-12">
|
<div class="col-sm-12">
|
||||||
<form method="POST" action="" >
|
<form method="POST" action="" novalidate>
|
||||||
{% csrf_token %}
|
{% csrf_token %}
|
||||||
<h3><i class="fa fa-key" aria-hidden="true"></i>{% trans "Access Key"%} </h3>
|
<h3><i class="fa fa-key" aria-hidden="true"></i>{% trans "Access Key"%} </h3>
|
||||||
{% if messages %}
|
{% if messages %}
|
||||||
|
@ -16,27 +16,24 @@
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<hr/>
|
{% for field in form %}
|
||||||
{% if not user_key %}
|
|
||||||
<h3>
|
{% bootstrap_field field %}
|
||||||
|
{% endfor %}
|
||||||
|
{% buttons %}
|
||||||
|
<button type="submit" class="btn btn-success">
|
||||||
{% trans "Upload your own key. "%}
|
{% trans "Upload your own key. "%}
|
||||||
</h3>
|
</button>
|
||||||
<div class="form-group">
|
<br />
|
||||||
<label for="comment">Paste here your public key</label>
|
<br />
|
||||||
<textarea class="form-control" rows="6" name="public_key"></textarea>
|
{% trans "Or generate a new key pair."%} <br />
|
||||||
</div>
|
<br />
|
||||||
<div class="form-group">
|
|
||||||
<button class="btn btn-success">{% trans "Upload Key"%} </a>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<h3>
|
|
||||||
{% trans "Or generate a new key pair."%}
|
|
||||||
|
|
||||||
</h3>
|
|
||||||
<div class="form-group">
|
|
||||||
<button class="btn btn-success">{% trans "Generate Key Pair"%} </a>
|
<button class="btn btn-success">{% trans "Generate Key Pair"%} </a>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
{% endbuttons %}
|
||||||
|
<div class="form-group">
|
||||||
</div>
|
</div>
|
||||||
{% else %}
|
|
||||||
<h5> Use your created key to access to the machine. If you lost it, contact us. </h5>
|
<h5> Use your created key to access to the machine. If you lost it, contact us. </h5>
|
||||||
<table class="table borderless table-hover">
|
<table class="table borderless table-hover">
|
||||||
<br/>
|
<br/>
|
||||||
|
@ -49,6 +46,7 @@
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
|
{% for user_key in keys %}
|
||||||
<tr>
|
<tr>
|
||||||
<td scope="row">{{user_key.name}}</td>
|
<td scope="row">{{user_key.name}}</td>
|
||||||
<td>{{user_key.created_at}}</td>
|
<td>{{user_key.created_at}}</td>
|
||||||
|
@ -57,9 +55,9 @@
|
||||||
|
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
{% endif %}
|
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
{% if private_key %}
|
{% if private_key %}
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
from django.test import TestCase
|
from django.test import TestCase
|
||||||
|
|
||||||
# Create your tests here.
|
# Create your tests here.
|
||||||
|
|
||||||
|
test_user_can_add_key()
|
||||||
|
|
|
@ -301,16 +301,12 @@ class GenerateVMSSHKeysView(LoginRequiredMixin, FormView):
|
||||||
self
|
self
|
||||||
).get_context_data(**kwargs)
|
).get_context_data(**kwargs)
|
||||||
|
|
||||||
try:
|
user_keys = UserHostingKey.objects.filter(
|
||||||
user_key = UserHostingKey.objects.get(
|
|
||||||
user=self.request.user
|
user=self.request.user
|
||||||
)
|
)
|
||||||
|
|
||||||
except UserHostingKey.DoesNotExist:
|
|
||||||
user_key = None
|
|
||||||
|
|
||||||
context.update({
|
context.update({
|
||||||
'user_key': user_key
|
'keys': user_keys
|
||||||
})
|
})
|
||||||
|
|
||||||
return context
|
return context
|
||||||
|
@ -351,23 +347,24 @@ class GenerateVMSSHKeysView(LoginRequiredMixin, FormView):
|
||||||
opennebula_user = user_pool.get_by_name(owner.email)
|
opennebula_user = user_pool.get_by_name(owner.email)
|
||||||
|
|
||||||
# Get user ssh key
|
# Get user ssh key
|
||||||
user_key = UserHostingKey.objects.get(user=owner)
|
public_key = form.cleaned_data.get('public_key')
|
||||||
# Add ssh key to user
|
# Add ssh key to user
|
||||||
manager.oneadmin_client.call('user.update', opennebula_user.id,
|
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))
|
'<CONTEXT><SSH_PUBLIC_KEY>{key}</SSH_PUBLIC_KEY></CONTEXT>'.format(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):
|
||||||
|
|
||||||
try:
|
# try:
|
||||||
UserHostingKey.objects.get(
|
# UserHostingKey.objects.get(
|
||||||
user=self.request.user
|
# user=self.request.user
|
||||||
)
|
# )
|
||||||
return HttpResponseRedirect(reverse('hosting:key_pair'))
|
# return HttpResponseRedirect(reverse('hosting:key_pair'))
|
||||||
|
|
||||||
|
# except UserHostingKey.DoesNotExist:
|
||||||
|
# pass
|
||||||
|
|
||||||
except UserHostingKey.DoesNotExist:
|
|
||||||
pass
|
|
||||||
|
|
||||||
form = self.get_form()
|
form = self.get_form()
|
||||||
if form.is_valid():
|
if form.is_valid():
|
||||||
|
|
|
@ -446,7 +446,7 @@ class OpenNebulaManager():
|
||||||
Args:
|
Args:
|
||||||
user (CustomUser): Dynamicweb user
|
user (CustomUser): Dynamicweb user
|
||||||
public_key (string): Public key to add to the user
|
public_key (string): Public key to add to the user
|
||||||
replace (bool): Optional if True the new public key replaces the old
|
merge (bool): Optional if True the new public key replaces the old
|
||||||
|
|
||||||
Raises:
|
Raises:
|
||||||
KeyExistsError: If replace is False and the user already has a
|
KeyExistsError: If replace is False and the user already has a
|
||||||
|
|
|
@ -42,7 +42,7 @@ class VirtualMachineTemplateSerializer(serializers.Serializer):
|
||||||
class VirtualMachineSerializer(serializers.Serializer):
|
class VirtualMachineSerializer(serializers.Serializer):
|
||||||
"""Serializer to map the virtual machine instance into JSON format."""
|
"""Serializer to map the virtual machine instance into JSON format."""
|
||||||
|
|
||||||
name = serializers.CharField(read_only=True)
|
name = serializers.SerializerMethodField()
|
||||||
cores = serializers.IntegerField(source='template.vcpu')
|
cores = serializers.IntegerField(source='template.vcpu')
|
||||||
disk = serializers.IntegerField(write_only=True)
|
disk = serializers.IntegerField(write_only=True)
|
||||||
set_memory = serializers.IntegerField(write_only=True, label='Memory')
|
set_memory = serializers.IntegerField(write_only=True, label='Memory')
|
||||||
|
@ -127,6 +127,8 @@ class VirtualMachineSerializer(serializers.Serializer):
|
||||||
nic = obj.template.nics[0]
|
nic = obj.template.nics[0]
|
||||||
return nic.ip6_global
|
return nic.ip6_global
|
||||||
|
|
||||||
|
def get_name(self, obj):
|
||||||
|
return obj.name.strip('public-')
|
||||||
|
|
||||||
def hexstr2int(string):
|
def hexstr2int(string):
|
||||||
return int(string.replace(':', ''), 16)
|
return int(string.replace(':', ''), 16)
|
||||||
|
|
|
@ -99,10 +99,70 @@ class OpenNebulaManagerTestCases(TestCase):
|
||||||
self.assertEqual(new_public_key, '{}\n{}'.format(old_public_key,
|
self.assertEqual(new_public_key, '{}\n{}'.format(old_public_key,
|
||||||
public_key))
|
public_key))
|
||||||
|
|
||||||
|
def test_remove_public_key_to_user(self):
|
||||||
|
""" Test the manager can remove a public key from an user """
|
||||||
|
self.manager.create_user(self.user)
|
||||||
|
user = self.manager._get_user(self.user)
|
||||||
|
public_key = 'test'
|
||||||
|
self.manager.add_public_key(self.user, public_key)
|
||||||
|
old_public_key = user.template.ssh_public_key
|
||||||
|
self.manager.remove_public_key(self.user, public_key)
|
||||||
|
user.info()
|
||||||
|
new_public_key = user.template.ssh_public_key
|
||||||
|
# Cleanup
|
||||||
|
user.delete()
|
||||||
|
|
||||||
|
self.assertEqual(new_public_key, old_public_key.replace(public_key, ''))
|
||||||
|
|
||||||
|
|
||||||
def test_requires_ssh_key_for_new_vm(self):
|
def test_requires_ssh_key_for_new_vm(self):
|
||||||
"""Test the opennebula manager requires the user to have a ssh key when
|
"""Test the opennebula manager requires the user to have a ssh key when
|
||||||
creating a new vm"""
|
creating a new vm"""
|
||||||
|
|
||||||
|
|
||||||
|
class VirtualMachineTestCase(TestCase):
|
||||||
|
def setUp(self):
|
||||||
|
"""Define the test client and other test variables."""
|
||||||
|
self.template_name = "Standard"
|
||||||
|
self.base_price = 0.0
|
||||||
|
self.core_price = 5.0
|
||||||
|
self.memory_price = 2.0
|
||||||
|
self.disk_size_price = 0.6
|
||||||
|
|
||||||
|
self.cores = 1
|
||||||
|
self.memory = 1
|
||||||
|
self.disk_size = 10.0
|
||||||
|
self.manager = OpenNebulaManager(email=None, password=None, create_user=False)
|
||||||
|
self.opennebula_id = self.manager.create_template(name=self.template_name,
|
||||||
|
cores=self.cores,
|
||||||
|
memory=self.memory,
|
||||||
|
disk_size=self.disk_size)
|
||||||
|
|
||||||
|
self.template = VirtualMachineTemplate(opennebula_id=self.opennebula_id,
|
||||||
|
base_price=self.base_price,
|
||||||
|
memory_price=self.memory_price,
|
||||||
|
core_price=self.core_price,
|
||||||
|
disk_size_price=self.disk_size_price)
|
||||||
|
self.template_id = self.template.opennebula_id()
|
||||||
|
self.opennebula_id = self.manager.create_virtualmachine(template_id=self.template_id)
|
||||||
|
|
||||||
|
self.virtualmachine = VirtualMachine(opennebula_id=self.opennebula_id,
|
||||||
|
template=self.template)
|
||||||
|
|
||||||
|
def test_serializer_strips_of_public(self):
|
||||||
|
""" Test the serialized object contains no 'public-'."""
|
||||||
|
|
||||||
|
template = self.manager.get_templates().first()
|
||||||
|
serialized = VirtualMachineTemplateSerializer(template)
|
||||||
|
self.assertEqual(serialized.data.name, template.name.strip('public-'))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def test_model_can_create_a_virtualmachine(self):
|
||||||
|
"""Test the virtualmachine model can create a virtualmachine."""
|
||||||
|
old_count = VirtualMachine.objects.count()
|
||||||
|
self.virtualmachine.save()
|
||||||
|
new_count = VirtualMachine.objects.count()
|
||||||
|
self.assertNotEqual(old_count, new_count)
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue