Merge pull request #308 from levivm/develop
Merging ssh fix from modulos
This commit is contained in:
		
				commit
				
					
						c38b36a8a5
					
				
			
		
					 7 changed files with 171 additions and 80 deletions
				
			
		|  | @ -85,7 +85,7 @@ | |||
|                           <ul id="g-account-menu" class="dropdown-menu" role="menu"> | ||||
|                             <li><a href="{% url 'hosting:logout' %}"><i class="glyphicon glyphicon-lock"></i>{% trans "Logout"%} </a></li> | ||||
| 							<li> | ||||
|                             <a href="{% url 'hosting:key_pair' %}"> | ||||
|                             <a href="{% url 'hosting:ssh_keys' %}"> | ||||
|                                 <i class="fa fa-key"></i> {% trans "Keys"%} | ||||
|                             </a> | ||||
|                         	</li> | ||||
|  | @ -149,7 +149,7 @@ | |||
|                         <li>⋅</li> | ||||
|                         <li> | ||||
|                         <li> | ||||
|                             <a href="{% url 'hosting:key_pair' %}"> | ||||
|                             <a href="{% url 'hosting:ssh_keys' %}"> | ||||
|                                 {% trans "Keys"%} | ||||
|                             </a> | ||||
|                         </li> | ||||
|  |  | |||
|  | @ -53,7 +53,7 @@ | |||
|                                             </button> | ||||
|                                         </div> | ||||
|                                         <div class="modal-body"> | ||||
|                                             <h4 class="modal-title" id="ModalLabel">{% trans "Do You want do delete your order?"%}</h4> | ||||
|                                             <h4 class="modal-title" id="ModalLabel">{% trans "Do You want to delete your order?"%}</h4> | ||||
| 
 | ||||
|                                             <form method="post" | ||||
|                                                   action="{% url 'hosting:delete_order' order.id %}"> | ||||
|  |  | |||
|  | @ -17,7 +17,6 @@ | |||
|                         </div> | ||||
| 						{% endif %} | ||||
|                         {% for field in form %} | ||||
| 							 | ||||
|                             {% bootstrap_field field %} | ||||
|                         {% endfor %} | ||||
|                         {% buttons %} | ||||
|  | @ -32,34 +31,8 @@ | |||
|                             </button> | ||||
| 
 | ||||
|                         {% endbuttons %}  | ||||
|                             <div class="form-group"> | ||||
|                             </div> | ||||
|                         {% else %} | ||||
| 						<h5> {% trans "Use your created key to access to the machine. If you lost it, contact us." %} </h5> | ||||
|                             <table class="table borderless table-hover">  | ||||
|                                 <br/> | ||||
|                                 <thead>  | ||||
|                                 <tr>  | ||||
|                                     <th>{% trans "Name"%}</th> | ||||
|                                     <th>{% trans "Created at"%} </th> | ||||
|                                     <th>{% trans "Status"%} </th> | ||||
|                                     <th></th> | ||||
|                                 </tr> | ||||
|                                 </thead> | ||||
|                                 <tbody>  | ||||
| 									{% for user_key in keys %} | ||||
|                                     <tr>  | ||||
|                                         <td scope="row">{{user_key.name}}</td>  | ||||
|                                         <td>{{user_key.created_at}}</td>  | ||||
|                                         <td> | ||||
|                                             <span class="h3 label label-success"><strong>Active</strong></span> | ||||
| 
 | ||||
|                                         </td>  | ||||
|                                     </tr> | ||||
| 									{% endfor %} | ||||
|                                 </tbody>  | ||||
|                             </table> | ||||
|                         </form> | ||||
|                         <h5> Use your created key to access to the machine. If you lost it, contact us. </h5> | ||||
| 
 | ||||
| 				        {% if private_key %} | ||||
| 				 		<div class="alert alert-warning"> | ||||
|  | @ -70,17 +43,7 @@ | |||
| 						  <textarea class="form-control" rows="6" id="ssh_key" type="hidden" style="display:none">{{private_key}}</textarea> | ||||
| 
 | ||||
| 						</div> | ||||
| <!-- 							<div  class="form-group pull-right"> | ||||
| 								<button type="button" id="copy_to_clipboard" data-clipboard-target="#ssh_key" class="btn btn-warning" | ||||
| 									data-toggle="tooltip"  data-placement="bottom" title="Copied"  data-trigger="click">{% trans "Copy to Clipboard"%}</button> | ||||
| 								<button type="button" id="download_ssh_key" class="btn btn-warning">{% trans "Download"%}</button>   | ||||
| 							</div> -->				         | ||||
| 						{% else %} | ||||
| <!-- 					 		<div class="alert alert-warning"> | ||||
| 	  							<strong>{% trans "Warning!"%}</strong>{% trans "Your SSH private key was already generated and downloaded, if you lost it, contact us. "%}  | ||||
| 							</div> | ||||
|  -->						{% endif %} | ||||
| 						<!-- <a class="btn btn-success" href="{% url 'hosting:virtual_machines' %}">{% trans "Generate my key"%} </a> --> | ||||
| 						{% endif %} | ||||
| 						<div class="clearfix"></div> | ||||
| 				</div> | ||||
| 			</div> | ||||
							
								
								
									
										96
									
								
								hosting/templates/hosting/user_keys.html
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										96
									
								
								hosting/templates/hosting/user_keys.html
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,96 @@ | |||
| {% extends "hosting/base_short.html" %} | ||||
| {% load staticfiles bootstrap3 i18n %} | ||||
| {% block content %}  | ||||
| <div> | ||||
| 	<div class="container virtual-machine-container dashboard-container "> | ||||
| 		<div class="row"> | ||||
| 			<div class="col-md-9 col-md-offset-2"> | ||||
| 				 <div  class="col-sm-12"> | ||||
|                     <h3><i class="fa fa-key" aria-hidden="true"></i>{% trans "Access Key"%} </h3> | ||||
|                     {% if messages %} | ||||
|                     <div class="alert alert-warning"> | ||||
|                         {% for message in messages %} | ||||
|                         <span>{{ message }}</span> | ||||
|                         {% endfor %} | ||||
|                     </div> | ||||
|                     {% endif %} | ||||
|                     <p class="pull-right"> | ||||
|                         <a class="btn btn-success" href="{% url 'hosting:create_ssh_key' %}" >{% trans "Add Key"%} </a> | ||||
|                     </p> | ||||
|                     <h5> Use your created key to access to the machine. If you lost it, contact us. </h5> | ||||
|                     <table class="table borderless table-hover">  | ||||
|                         <br/> | ||||
|                         <thead>  | ||||
|                         <tr>  | ||||
|                             <th>{% trans "Name"%}</th> | ||||
|                             <th>{% trans "Created at"%} </th> | ||||
|                             <th>{% trans "Status"%} </th> | ||||
|                             <th></th> | ||||
|                         </tr> | ||||
|                         </thead> | ||||
|                         <tbody>  | ||||
|                             {% for user_key in keys %} | ||||
|                             <tr>  | ||||
|                                 <td scope="row">{{user_key.name}}</td>  | ||||
|                                 <td>{{user_key.created_at}}</td>  | ||||
|                                 <td> | ||||
|                                     <span class="h3 label label-success"><strong>Active</strong></span> | ||||
|                                 </td>  | ||||
|                                 <td>  | ||||
|                                 <button type="button" class="btn btn-default" data-toggle="modal" | ||||
|                                         data-target="#Modal{{ user_key.id }}"><a | ||||
|                                         href="#">{% trans "Delete Key"%}</a> | ||||
|                                 </button> | ||||
| 
 | ||||
|     <div class="modal fade" id="Modal{{user_key.id }}" tabindex="-1" role="dialog"> | ||||
|         <div class="modal-dialog" role="document"> | ||||
|             <div class="modal-content"> | ||||
|                 <div class="modal-header"> | ||||
|                     <button type="button" class="close" data-dismiss="modal" | ||||
|                             aria-label="Confirm"><span | ||||
|                             aria-hidden="true">×</span> | ||||
|                     </button> | ||||
|                 </div> | ||||
|                 <div class="modal-body"> | ||||
|                     <h4 class="modal-title" id="ModalLabel">{% trans "Do You want to delete this key?"%}</h4> | ||||
| 
 | ||||
|                     <form method="post" action="{% url 'hosting:delete_ssh_key' user_key.id %}"> | ||||
|                         {% csrf_token %} | ||||
|                         <div class="modal-footer"> | ||||
|                             <button type="button" class="btn btn-default" | ||||
|                                     data-dismiss="modal"> | ||||
|                                 {% trans "Close"%} | ||||
|                             </button> | ||||
|                             <button type="submit" class="btn btn-primary">{% trans "Delete"%} | ||||
|                             </button> | ||||
|                         </div> | ||||
|                     </form> | ||||
|                 </div> | ||||
|             </div> | ||||
|         </div> | ||||
|     </div> | ||||
|                                  </td> | ||||
|                             </tr> | ||||
|                             {% endfor %} | ||||
|                                 </tbody>  | ||||
|                             </table> | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 						<div class="clearfix"></div> | ||||
| 				</div> | ||||
| 			</div> | ||||
| 
 | ||||
| 	    </div> | ||||
| 	</div> | ||||
|      | ||||
| </div> | ||||
| 
 | ||||
| {% if next_url %} | ||||
|     <script type="text/javascript">  | ||||
|         window.location.href = '{{next_url}}'; | ||||
|     </script> | ||||
| {% endif %} | ||||
| 
 | ||||
| {%endblock%} | ||||
| 
 | ||||
|  | @ -2,4 +2,6 @@ from django.test import TestCase | |||
| 
 | ||||
| # Create your tests here. | ||||
| 
 | ||||
| test_user_can_add_key() | ||||
| test_user_can_add_ssh_key() | ||||
| 
 | ||||
| test_user_can_delete_ssh_ke() | ||||
|  |  | |||
|  | @ -3,9 +3,10 @@ from django.conf.urls import url | |||
| from .views import DjangoHostingView, RailsHostingView, PaymentVMView,\ | ||||
|     NodeJSHostingView, LoginView, SignupView, IndexView, \ | ||||
|     OrdersHostingListView, OrdersHostingDetailView, VirtualMachinesPlanListView,\ | ||||
|     VirtualMachineView, GenerateVMSSHKeysView, OrdersHostingDeleteView, NotificationsView, \ | ||||
|     VirtualMachineView, OrdersHostingDeleteView, NotificationsView, \ | ||||
|     MarkAsReadNotificationView, PasswordResetView, PasswordResetConfirmView, HostingPricingView,\ | ||||
|     CreateVirtualMachinesView, HostingBillListView, HostingBillDetailView | ||||
|     CreateVirtualMachinesView, HostingBillListView, HostingBillDetailView, \ | ||||
|     SSHKeyDeleteView, SSHKeyCreateView, SSHKeyListView | ||||
| 
 | ||||
| urlpatterns = [ | ||||
|     url(r'index/?$', IndexView.as_view(), name='index'), | ||||
|  | @ -23,10 +24,12 @@ urlpatterns = [ | |||
|     url(r'my-virtual-machines/?$', VirtualMachinesPlanListView.as_view(), name='virtual_machines'), | ||||
|     url(r'my-virtual-machines/(?P<pk>\d+)/?$', VirtualMachineView.as_view(), | ||||
|         name='virtual_machines'), | ||||
|     # url(r'my-virtual-machines/(?P<pk>\d+)/delete/?$', VirtualMachineCancelView.as_view(), | ||||
|         # name='virtual_machines_cancel'), | ||||
|     url(r'vm-key-pair/?$', GenerateVMSSHKeysView.as_view(), | ||||
|         name='key_pair'), | ||||
|     url(r'ssh_keys/?$', SSHKeyListView.as_view(), | ||||
|         name='ssh_keys'), | ||||
|     url(r'delete_ssh_key/(?P<pk>\d+)/?$', SSHKeyDeleteView.as_view(), | ||||
|         name='delete_ssh_key'), | ||||
|     url(r'create_ssh_key/?$', SSHKeyCreateView.as_view(), | ||||
|         name='create_ssh_key'), | ||||
|     url(r'^notifications/$', NotificationsView.as_view(), name='notifications'), | ||||
|     url(r'^notifications/(?P<pk>\d+)/?$', MarkAsReadNotificationView.as_view(), | ||||
|         name='read_notification'), | ||||
|  |  | |||
|  | @ -188,7 +188,7 @@ class SignupView(CreateView): | |||
|     template_name = 'hosting/signup.html' | ||||
|     form_class = HostingUserSignupForm | ||||
|     model = CustomUser | ||||
|     success_url = reverse_lazy('hosting:key_pair') | ||||
|     success_url = reverse_lazy('hosting:ssh_keys') | ||||
| 
 | ||||
|     def get_success_url(self): | ||||
|         next_url = self.request.session.get( | ||||
|  | @ -288,31 +288,58 @@ class MarkAsReadNotificationView(LoginRequiredMixin, UpdateView): | |||
|         return HttpResponseRedirect(reverse('hosting:notifications')) | ||||
| 
 | ||||
| 
 | ||||
| class GenerateVMSSHKeysView(LoginRequiredMixin, FormView): | ||||
| class SSHKeyDeleteView(LoginRequiredMixin, DeleteView): | ||||
|     login_url = reverse_lazy('hosting:login') | ||||
|     success_url = reverse_lazy('hosting:ssh_keys') | ||||
|     model = UserHostingKey | ||||
| 
 | ||||
|     def delete(self, request, *args, **kwargs): | ||||
|         owner = self.request.user | ||||
|         manager = OpenNebulaManager() | ||||
|         pk = self.kwargs.get('pk') | ||||
|         # Get user ssh key | ||||
|         public_key = UserHostingKey.objects.get(pk=pk) | ||||
|         # Add ssh key to user | ||||
|         try: | ||||
|             manager.remove_public_key(user=owner, public_key=public_key) | ||||
|         except ConnectionError: | ||||
|             pass | ||||
|         except WrongNameError: | ||||
|             pass | ||||
| 
 | ||||
|         return super(SSHKeyDeleteView, self).delete(request, *args, **kwargs) | ||||
| 
 | ||||
| class SSHKeyListView(LoginRequiredMixin, ListView): | ||||
|     template_name = "hosting/user_keys.html" | ||||
|     login_url = reverse_lazy('hosting:login') | ||||
|     context_object_name = "keys" | ||||
|     model = UserHostingKey | ||||
|     paginate_by = 10 | ||||
|     ordering = '-id' | ||||
| 
 | ||||
| 
 | ||||
|     def get_queryset(self): | ||||
|         user = self.request.user | ||||
|         self.queryset = UserHostingKey.objects.filter(user=user) | ||||
|         return super(SSHKeyListView, self).get_queryset() | ||||
| 
 | ||||
|     def render_to_response(self, context, **response_kwargs): | ||||
|         if not self.queryset: | ||||
|             return HttpResponseRedirect(reverse('hosting:create_ssh_key')) | ||||
|         return super(SSHKeyListView, self).render_to_response(context, **response_kwargs) | ||||
| 
 | ||||
| 
 | ||||
| class SSHKeyCreateView(LoginRequiredMixin, FormView): | ||||
|     form_class = UserHostingKeyForm | ||||
|     model = UserHostingKey | ||||
|     template_name = 'hosting/virtual_machine_key.html' | ||||
|     template_name = 'hosting/user_key.html' | ||||
|     login_url = reverse_lazy('hosting:login') | ||||
|     context_object_name = "virtual_machine" | ||||
|     success_url = reverse_lazy('hosting:ssh_keys') | ||||
| 
 | ||||
|     def get_context_data(self, **kwargs): | ||||
|         context = super( | ||||
|             GenerateVMSSHKeysView, | ||||
|             self | ||||
|         ).get_context_data(**kwargs) | ||||
| 
 | ||||
|         user_keys = UserHostingKey.objects.filter( | ||||
|             user=self.request.user | ||||
|         ) | ||||
| 
 | ||||
|         context.update({ | ||||
|             'keys': user_keys | ||||
|         }) | ||||
| 
 | ||||
|         return context | ||||
| 
 | ||||
|     def get_form_kwargs(self): | ||||
|         kwargs = super(GenerateVMSSHKeysView, self).get_form_kwargs() | ||||
|         kwargs = super(SSHKeyCreateView, self).get_form_kwargs() | ||||
|         kwargs.update({'request': self.request}) | ||||
|         return kwargs | ||||
| 
 | ||||
|  | @ -339,22 +366,22 @@ class GenerateVMSSHKeysView(LoginRequiredMixin, FormView): | |||
|             }) | ||||
| 
 | ||||
|         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) | ||||
|         manager = OpenNebulaManager() | ||||
| 
 | ||||
|         # Get user ssh key | ||||
|         public_key = form.cleaned_data.get('public_key') | ||||
|         # Add ssh key to user | ||||
|         manager.oneadmin_client.call('user.update', opennebula_user.id, | ||||
|                                      '<CONTEXT><SSH_PUBLIC_KEY>{key}</SSH_PUBLIC_KEY></CONTEXT>'.format(key=public_key)) | ||||
|         try: | ||||
|             manager.add_public_key(user=owner, public_key=public_key, merge=True) | ||||
|         except ConnectionError: | ||||
|             pass | ||||
|         except WrongNameError: | ||||
|             pass | ||||
| 
 | ||||
|         return render(self.request, self.template_name, context) | ||||
|         return HttpResponseRedirect(self.success_url) | ||||
| 
 | ||||
|     def post(self, request, *args, **kwargs): | ||||
|         print(self.request.POST.dict()) | ||||
|         form = self.get_form() | ||||
|         if form.is_valid(): | ||||
|             return self.form_valid(form) | ||||
|  | @ -412,7 +439,7 @@ class PaymentVMView(LoginRequiredMixin, FormView): | |||
|                 request, | ||||
|                 'In order to create a VM, you create/upload your SSH KEY first.' | ||||
|             ) | ||||
|             return HttpResponseRedirect(reverse('hosting:key_pair')) | ||||
|             return HttpResponseRedirect(reverse('hosting:ssh_keys')) | ||||
| 
 | ||||
|         if 'next' in request.session: | ||||
|             del request.session['next'] | ||||
|  | @ -628,7 +655,7 @@ class CreateVirtualMachinesView(LoginRequiredMixin, View): | |||
|                 request, | ||||
|                 'In order to create a VM, you need to create/upload your SSH KEY first.' | ||||
|             ) | ||||
|             return HttpResponseRedirect(reverse('hosting:key_pair')) | ||||
|             return HttpResponseRedirect(reverse('hosting:ssh_keys')) | ||||
| 
 | ||||
|         try: | ||||
|             manager = OpenNebulaManager() | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue