Commit 9e534120 by Kálmán Viktor

dashboard: vm password change

parent 1d7e04a8
......@@ -241,3 +241,16 @@ a.hover-black {
text-align: right;
}
/* vm details connection */
.vm-details-pw dd {
margin-left: 155px;
}
.vm-details-pw dt {
width: 140px;
}
#vm-details-pw-confirm {
margin-top: 10px;
display: none;
}
......@@ -87,6 +87,57 @@ $(function() {
});
return false;
});
/* for js fallback */
$("#vm-details-pw-show").parent("div").children("input").prop("type", "password");
/* show password */
$("#vm-details-pw-show").click(function() {
var input = $(this).parent("div").children("input");
var eye = $(this).children("#vm-details-pw-eye");
eye.tooltip("destroy")
if(eye.hasClass("icon-eye-open")) {
eye.removeClass("icon-eye-open").addClass("icon-eye-close");
input.prop("type", "text");
input.focus();
eye.prop("title", "Hide password");
} else {
eye.removeClass("icon-eye-close").addClass("icon-eye-open");
input.prop("type", "password");
eye.prop("title", "Show password");
}
eye.tooltip();
});
/* change password confirmation */
$("#vm-details-pw-change").click(function() {
$("#vm-details-pw-confirm").fadeIn();
return false;
});
/* change password */
$(".vm-details-pw-confirm-choice").click(function() {
choice = $(this).data("choice");
if(choice) {
pk = $(this).data("vm");
$.ajax({
type: 'POST',
url: "/dashboard/vm/" + pk + "/",
data: {'change_password': 'true'},
headers: {"X-CSRFToken": getCookie('csrftoken')},
success: function(re, textStatus, xhr) {
location.reload();
},
error: function(xhr, textStatus, error) {
}
});
} else {
$("#vm-details-pw-confirm").fadeOut();
}
return false;
});
});
......
......@@ -33,12 +33,30 @@
</div>
</div>
<h3>{% trans "Connection" %}</h3>
<!-- TODO RDP -->
<input type="text" value="ssh cloud@vm.ik.bme.hu -p22312" class="form-control" readonly />
<dl class="dl-horizontal">
<dt>Etiam at felis:</dt>
<dd>condimentum lig igulaulal ulaligula vel</dd>
<dt>Vivamus nec:</dt>
<dd>ac metus interdum, tincidunt</dd>
<dl class="dl-horizontal vm-details-pw">
<dt>Password:</dt>
<dd>
<div class="input-group">
<input type="text" class="form-control input-sm input-tags" value="{{ instance.pw }}"/>
<span class="input-group-addon input-tags" id="vm-details-pw-show">
<i class="icon-eye-open" id="vm-details-pw-eye" title="Show password"></i>
</span>
</div>
</dd>
<dd style="font-size: 10px; text-align: right; padding-top: 8px;">
<a id="vm-details-pw-change" href="#">Generate new password!</a>
</dd>
<div id="vm-details-pw-confirm">
<dt>
Are you sure?
</dt>
<dd>
<a href="#" class="vm-details-pw-confirm-choice label label-success" data-choice="1" data-vm="{{ instance.pk }}">Yes</a> /
<a href="#" class="vm-details-pw-confirm-choice label label-danger" data-choice="0">No</a>
</dd>
</div>
</dl>
</div>
<div class="col-md-8" id="vm-detail-pane">
......
......@@ -103,3 +103,13 @@ class VmDetailTest(TestCase):
inst.set_level(self.u2, 'owner')
response = c.post('/dashboard/vm/mass-delete/', {'vms': [1]})
self.assertEqual(response.status_code, 302)
def test_unpermitted_password_change(self):
c = Client()
self.login(c, "user2")
inst = Instance.objects.get(pk=1)
inst.set_level(self.u1, 'owner')
password = inst.pw
response = c.post("/dashboard/vm/1/", {'change_password': True})
self.assertEqual(response.status_code, 403)
self.assertEqual(password, inst.pw)
......@@ -148,17 +148,30 @@ class VmDetailView(CheckedDetailView):
and request.POST.get('cpu-priority')):
return self.__set_resources(request)
if request.POST.get('new_name'):
return self.__set_name(request)
options = {
'change_password': self.__change_password,
'new_name': self.__set_name,
'new_tag': self.__add_tag,
'to_remove': self.__remove_tag,
'port': self.__add_port
}
if request.POST.get('new_tag') is not None:
return self.__add_tag(request)
for k, v in options.iteritems():
if request.POST.get(k) is not None:
return v(request)
if request.POST.get("to_remove") is not None:
return self.__remove_tag(request)
def __change_password(self, request):
self.object = self.get_object()
if not self.object.has_level(request.user, 'owner'):
raise PermissionDenied()
if request.POST.get("port") is not None:
return self.__add_port(request)
self.object.change_password(user=request.user)
messages.success(request, _("Password changed!"))
if request.is_ajax():
return HttpResponse("Success!")
else:
return redirect(reverse_lazy("dashboard.views.detail",
kwargs={'pk': self.object.pk}))
def __set_resources(self, request):
self.object = self.get_object()
......
......@@ -19,7 +19,7 @@ from taggit.managers import TaggableManager
from acl.models import AclBase
from storage.models import Disk
from ..tasks import local_tasks, vm_tasks
from ..tasks import local_tasks, vm_tasks, agent_tasks
from .activity import instance_activity
from .common import BaseResourceConfigModel, Lease
from .network import Interface
......@@ -454,6 +454,23 @@ class Instance(AclBase, VirtualMachineDescModel, TimeStampedModel):
self.time_of_delete = timezone.now() + self.lease.delete_interval
self.save()
def change_password(self, user=None):
"""Generate new password for the vm
:param self: The virtual machine.
:param user: The user who's issuing the command.
"""
self.pw = pwgen()
with instance_activity(code_suffix='change_password', instance=self,
user=user):
queue = "%s.agent" % self.node.host.hostname
agent_tasks.change_password.apply_async(queue=queue,
args=(self.vm_name,
self.pw))
self.save()
def __schedule_vm(self, act):
"""Schedule the virtual machine.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment