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…
	
	Add table
		Add a link
		
	
		Reference in a new issue