Commit 651a6105 by Kálmán Viktor

dashboard: open and close ports

parent d798a61b
......@@ -194,3 +194,17 @@ body {
border-radius: 3px;
}
/* --- */
.vm-details-remove-port:hover {
text-decoration: none;
}
/* arrow in port add table */
#ipv4 tbody td:nth-child(2), #ipv6 tbody td:nth-child(2) {
width: 60px;
}
/* port add buttons */
.vm-details-network-port-add .input-group-addon, .vm-details-network-port-add .input-group-btn {
width: inherit ;
}
......@@ -75,8 +75,39 @@ $(function() {
});
return false;
});
/* remove port */
$('.vm-details-remove-port').click(function() {
addModalConfirmation(removePort,
{
'url': $(this).prop("href"),
'data': [],
'rule': $(this).data("rule")
});
return false;
});
});
function removePort(data) {
$.ajax({
type: 'POST',
url: data['url'],
headers: {"X-CSRFToken": getCookie('csrftoken')},
success: function(re, textStatus, xhr) {
$("a[data-rule=" + data['rule'] + "]").each(function() {
$(this).closest("tr").fadeOut(500, function() {
$(this).remove();
});
});
addMessage(re['message'], "success");
},
error: function(xhr, textStatus, error) {
}
});
}
function checkNewActivity() {
var latest = $('.activity:first').data('activity-id');
var latest_sub = $('div[data-activity-id="' + latest + '"] .sub-timeline .sub-activity:first').data('activity-id');
......
......@@ -3,9 +3,13 @@
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-body">
{% if text %}
{{ text }}
{% else %}
{%blocktrans with object=object%}
Are you sure you want to delete <strong>{{ object }}</strong>?
Are you sure you want to delete <strong>{{ object }}</strong>?
{%endblocktrans%}
{% endif %}
<br />
<div class="pull-right" style="margin-top: 15px;">
<button type="button" class="btn btn-default" data-dismiss="modal">Cancel</button>
......
......@@ -6,13 +6,21 @@
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="no-margin">
Delete confirmation
{% if title %}
{{ title }}
{% else %}
Delete confirmation
{% endif %}
</h3>
</div>
<div class="panel-body">
{%blocktrans with object=object%}
Are you sure you want to delete <strong>{{ object }}</strong>?
{%endblocktrans%}
{% if text %}
{{ text }}
{% else %}
{%blocktrans with object=object%}
Are you sure you want to delete <strong>{{ object }}</strong>?
{%endblocktrans%}
{% endif %}
<div class="pull-right">
<form action="" method="POST">
{% csrf_token %}
......
<tfoot>
<tr>
<td style="vertical-align: middle;">
<i class="icon-plus"></i> <i class="icon-long-arrow-right"></i>
</td>
<td colspan="2">
<div class="input-group input-group-sm">
<input type="text" class="form-control" size="5" />
<span class="input-group-addon">/</span>
<select class="form-control"><option>tcp</option><option>udp</option></select>
</div>
</td>
<td>
<button type="submit" class="btn btn-success btn-sm">Add</button>
</td>
</tr>
</tfoot>
{% load i18n %}
<div class="vm-details-network-port-add pull-right">
<form action="" method="POST">
{% csrf_token %}
<input type="hidden" name="host_pk" value="{{ i.host.pk }}"/>
<div class="input-group input-group-sm">
<span class="input-group-addon">
<i class="icon-plus"></i> <i class="icon-long-arrow-right"></i>
</span>
<input type="text" class="form-control" size="5" style="width: 80px;" name="port"/>
<span class="input-group-addon">/</span>
<select class="form-control" name="proto" style="width: 70px;"><option>tcp</option><option>udp</option></select>
<div class="input-group-btn">
<button type="submit" class="btn btn-success btn-sm">{% trans "Add" %}</button>
</div>
</div>
</form>
</div>
......@@ -44,31 +44,27 @@ Interfaces</h2>
</th></tr>
</thead>
<tbody>
<!-- inline td width shall be replaced -->
{% for l in i.host.list_ports %}
{% if l.ipv4 %}
<tr>
<td>
{{ l.ipv4.host }}:{{ l.ipv4.port }}
</td>
<td style="width: 61px;"><i class="icon-long-arrow-right"></i></td>
<td style="width: 111px;">
<td><i class="icon-long-arrow-right"></i></td>
<td>
{{ l.private }}/{{ l.proto }}
</td>
<td>
<a href="#" class="btn btn-link btn-xs" title="{% trans "Remove" %}"><i class="icon-remove"><span class="sr-only">{% trans "Remove" %}</span></i></a>
<a href="{% url "dashboard.views.remove-port" pk=instance.pk rule=l.ipv4.pk %}" class="btn btn-link btn-xs vm-details-remove-port" data-rule="{{ l.ipv4.pk }}" title="{% trans "Remove" %}"><i class="icon-remove"><span class="sr-only">{% trans "Remove" %}</span></i></a>
</td>
</tr>
{% endif %}
{% endfor %}
<tr><td>vm.ik.bme.hu:22620</td><td><i class="icon-long-arrow-right"></i></td><td><abbr title="ssh">22</abbr>/tcp</td><td><a href="#" class="btn btn-link btn-xs" title="remove"><i class="icon-remove"><span class="sr-only">{% trans "remove" %}</span></i></a></td></tr>
<tr><td>vm.ik.bme.hu:22620</td><td><i class="icon-long-arrow-right"></i></td><td>12344/tcp</td><td><a href="#" class="btn btn-link btn-xs" title="remove"><i class="icon-remove"><span class="sr-only">{% trans "remove" %}</span></i></a></td></tr>
<tr><td>vm.ik.bme.hu:22620</td><td><i class="icon-long-arrow-right"></i></td><td><abbr title="http-alt">8080</abbr>/tcp</td><td><a href="#" class="btn btn-link btn-xs" title="remove"><i class="icon-remove"><span class="sr-only">{% trans "remove" %}</span></i></a></td></tr>
</tbody>
{% include "dashboard/vm-detail-network-port-add.html" %}
</table>
</div> <!-- /ipv4 -->
<div class="tab-pane" id="ipv6">
{% if i.host.ipv6 %}
<table class="table table-striped rule-table">
<thead>
<tr><th>
......@@ -80,30 +76,29 @@ Interfaces</h2>
</th></tr>
</thead>
<tbody>
<!-- inline td width TODO not do it -->
{% for l in i.host.list_ports %}
{% if l.ipv6 %}
<tr>
<td>
{{ l.ipv6.host }}:{{ l.ipv6.port }}
</td>
<td style="width: 61px;"><i class="icon-long-arrow-right"></i></td>
<td style="width: 111px;">
<td><i class="icon-long-arrow-right"></i></td>
<td>
{{ l.private }}/{{ l.proto }}
</td>
<td>
<a href="#" class="btn btn-link btn-xs" title="{% trans "Remove" %}"><i class="icon-remove"><span class="sr-only">{% trans "Remove" %}</span></i></a>
<a href="{% url "dashboard.views.remove-port" pk=instance.pk rule=l.ipv4.pk %}" class="btn btn-link btn-xs vm-details-remove-port" data-rule="{{ l.ipv6.pk }}" title="{% trans "Remove" %}"><i class="icon-remove"><span class="sr-only">{% trans "Remove" %}</span></i></a>
</td>
</tr>
{% endif %}
{% endfor %}
<tr><td>550.vm.ik.bme.hu:22</td><td><i class="icon-long-arrow-right"></i></td><td><abbr title="ssh">22</abbr>/tcp</td><td><a href="#" class="btn btn-link btn-xs" title="remove"><i class="icon-remove"><span class="sr-only">{% trans "remove" %}</span></i></a></td></tr>
<tr><td>550.vm.ik.bme.hu:12344</td><td><i class="icon-long-arrow-right"></i></td><td>12344/tcp</td><td><a href="#" class="btn btn-link btn-xs" title="remove"><i class="icon-remove"><span class="sr-only">{% trans "remove" %}</span></i></a></td></tr>
<tr><td>550.vm.ik.bme.hu:8080</td><td><i class="icon-long-arrow-right"></i></td><td><abbr title="http-alt">8080</abbr>/tcp</td><td><a href="#" class="btn btn-link btn-xs" title="remove"><i class="icon-remove"><span class="sr-only">{% trans "remove" %}</span></i></a></td></tr>
</tbody>
{% include "dashboard/vm-detail-network-port-add.html" %}
</table>
</div>
{% else %}
<h4>{% trans "This VM doesn't have an IPv6 address!" %}</h4>
{% endif %}
</div><!-- /ipv6 -->
{% include "dashboard/vm-detail-network-port-add.html" %}
</div>
</div>
</div>
......
......@@ -3,7 +3,7 @@ from django.conf.urls import patterns, url
from vm.models import Instance
from .views import (
IndexView, VmDetailView, VmList, VmCreate, TemplateDetail, AclUpdateView,
VmDelete, VmMassDelete, vm_activity, NodeList, NodeDetailView,
VmDelete, VmMassDelete, vm_activity, NodeList, NodeDetailView, PortDelete,
TransferOwnershipView, TransferOwnershipConfirmView
)
......@@ -12,6 +12,8 @@ urlpatterns = patterns(
url(r'^$', IndexView.as_view(), name="dashboard.index"),
url(r'^template/(?P<pk>\d+)/$', TemplateDetail.as_view(),
name='dashboard.views.template-detail'),
url(r'^vm/(?P<pk>\d+)/remove_port/(?P<rule>\d+)/$', PortDelete.as_view(),
name='dashboard.views.remove-port'),
url(r'^vm/(?P<pk>\d+)/$', VmDetailView.as_view(),
name='dashboard.views.detail'),
url(r'^vm/(?P<pk>\d+)/acl/$', AclUpdateView.as_view(model=Instance),
......
......@@ -22,7 +22,7 @@ from braces.views import LoginRequiredMixin
from .tables import (VmListTable, NodeListTable)
from vm.models import (Instance, InstanceTemplate, InterfaceTemplate,
InstanceActivity, Node, instance_activity)
from firewall.models import Vlan
from firewall.models import Vlan, Host, Rule
from storage.models import Disk
logger = logging.getLogger(__name__)
......@@ -120,6 +120,9 @@ class VmDetailView(CheckedDetailView):
if request.POST.get("to_remove") is not None:
return self.__remove_tag(request)
if request.POST.get("port") is not None:
return self.__add_port(request)
def __set_resources(self, request):
self.object = self.get_object()
if not self.object.has_level(request.user, 'owner'):
......@@ -201,6 +204,31 @@ class VmDetailView(CheckedDetailView):
content_type="application=json"
)
def __add_port(self, request):
object = self.get_object()
if not object.has_level(request.user, 'owner'):
raise PermissionDenied()
port = request.POST.get("port")
proto = request.POST.get("proto")
try:
error = None
host = Host.objects.get(pk=request.POST.get("host_pk"))
host.add_port(proto, private=port)
except Host.DoesNotExist:
error = _("Host not found!")
except Exception, e:
error = u', '.join(e.messages)
if request.is_ajax():
pass
else:
if error:
messages.error(request, error)
return redirect(reverse_lazy("dashboard.views.detail",
kwargs={'pk': self.get_object().pk}))
class NodeDetailView(DetailView):
template_name = "dashboard/node-detail.html"
......@@ -389,6 +417,7 @@ class VmDelete(DeleteView):
def get_context_data(self, **kwargs):
# this is redundant now, but if we wanna add more to print
# we'll need this
print kwargs
context = super(VmDelete, self).get_context_data(**kwargs)
return context
......@@ -421,6 +450,52 @@ class VmDelete(DeleteView):
return reverse_lazy('dashboard.index')
class PortDelete(DeleteView):
model = Rule
pk_url_kwarg = 'rule'
def get_template_names(self):
if self.request.is_ajax():
return ['dashboard/confirm/ajax-delete.html']
else:
return ['dashboard/confirm/base-delete.html']
def get_context_data(self, **kwargs):
context = super(PortDelete, self).get_context_data(**kwargs)
rule = kwargs.get('object')
instance = rule.host.interface_set.get().instance
context['title'] = _("Port delete confirmation")
context['text'] = _("Are you sure you want to close %(port)d/"
"%(proto)s on %(vm)s?" % {'port': rule.dport,
'proto': rule.proto,
'vm': instance})
return context
def delete(self, request, *args, **kwargs):
rule = Rule.objects.get(pk=kwargs.get("rule"))
instance = rule.host.interface_set.get().instance
if not instance.has_level(request.user, 'owner'):
raise PermissionDenied()
super(PortDelete, self).delete(request, *args, **kwargs)
success_url = self.get_success_url()
success_message = _("Port successfully removed!")
if request.is_ajax():
return HttpResponse(
json.dumps({'message': success_message}),
content_type="application/json",
)
else:
messages.success(request, success_message)
return HttpResponseRedirect("%s#network" % success_url)
def get_success_url(self):
return reverse_lazy('dashboard.views.detail',
kwargs={'pk': self.kwargs.get("pk")})
class VmMassDelete(View):
def get(self, request, *args, **kwargs):
vms = request.GET.getlist('v[]')
......
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