Commit eb3f55b3 by Bach Dániel

dashboard: add AddPortOperation

Closes #294
parent 5816bf02
......@@ -964,6 +964,41 @@ class VmPortRemoveForm(OperationForm):
return helper
class VmPortAddForm(OperationForm):
port = forms.IntegerField(required=True, label=_('Port'),
min_value=1, max_value=65535)
proto = forms.ChoiceField((('tcp', 'tcp'), ('udp', 'udp')),
required=True, label=_('Protocol'))
def __init__(self, *args, **kwargs):
choices = kwargs.pop('choices')
self.host = kwargs.pop('default')
super(VmPortAddForm, self).__init__(*args, **kwargs)
self.fields.insert(0, 'host', forms.ModelChoiceField(
queryset=choices, initial=self.host, required=True,
empty_label=None, label=_('Host')))
if self.host:
self.fields['host'].widget = HiddenInput()
@property
def helper(self):
helper = super(VmPortAddForm, self).helper
if self.host:
helper.layout = Layout(
AnyTag(
"div",
HTML(format_html(_("<label>Host:</label> {0}"), self.host)),
css_class="form-group",
),
Field("host"),
Field("proto"),
Field("port"),
)
return helper
class CircleAuthenticationForm(AuthenticationForm):
# fields: username, password
......
{% load i18n %}
<div class="vm-details-network-port-add pull-right">
<form action="" method="POST">
<form action="{{ op.add_port.get_url }}" method="POST">
{% csrf_token %}
<input type="hidden" name="host_pk" value="{{ i.host.pk }}"/>
<input type="hidden" name="host" value="{{ i.host.pk }}"/>
<div class="input-group input-group-sm">
<span class="input-group-addon">
<i class="fa fa-plus"></i> <i class="fa fa-long-arrow-right"></i>
</span>
<input type="text" class="form-control" size="5" style="width: 80px;" name="port"/>
<input type="number" class="form-control" size="5" min="1" max="65535"
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">
......
......@@ -62,7 +62,7 @@ from ..forms import (
VmRenewForm, VmStateChangeForm, VmListSearchForm, VmCustomizeForm,
TransferOwnershipForm, VmDiskResizeForm, RedeployForm, VmDiskRemoveForm,
VmMigrateForm, VmDeployForm,
VmPortRemoveForm,
VmPortRemoveForm, VmPortAddForm,
)
from ..models import Favourite, Profile
......@@ -175,7 +175,6 @@ class VmDetailView(GraphMixin, CheckedDetailView):
'new_description': self.__set_description,
'new_tag': self.__add_tag,
'to_remove': self.__remove_tag,
'port': self.__add_port,
'abort_operation': self.__abort_operation,
}
for k, v in options.iteritems():
......@@ -271,39 +270,6 @@ class VmDetailView(GraphMixin, CheckedDetailView):
return redirect(reverse_lazy("dashboard.views.detail",
kwargs={'pk': self.object.pk}))
def __add_port(self, request):
object = self.get_object()
if not (object.has_level(request.user, "operator") and
request.user.has_perm('vm.config_ports')):
raise PermissionDenied()
port = request.POST.get("port")
proto = request.POST.get("proto")
try:
error = None
interfaces = object.interface_set.all()
host = Host.objects.get(pk=request.POST.get("host_pk"),
interface__in=interfaces)
host.add_port(proto, private=port)
except Host.DoesNotExist:
logger.error('Tried to add port to nonexistent host %d. User: %s. '
'Instance: %s', request.POST.get("host_pk"),
unicode(request.user), object)
raise PermissionDenied()
except ValueError:
error = _("There is a problem with your input.")
except Exception as e:
error = _("Unknown error.")
logger.error(e)
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}))
def __abort_operation(self, request):
self.object = self.get_object()
......@@ -478,6 +444,32 @@ class VmPortRemoveView(FormOperationMixin, VmOperationView):
return val
class VmPortAddView(FormOperationMixin, VmOperationView):
op = 'add_port'
show_in_toolbar = False
with_reload = True
icon = 'times'
effect = "success"
form_class = VmPortAddForm
def get_form_kwargs(self):
instance = self.get_op().instance
choices = Host.objects.filter(interface__instance=instance)
host_pk = self.request.GET.get('host')
if host_pk:
try:
default = choices.get(pk=host_pk)
except (ValueError, Host.DoesNotExist):
raise Http404()
else:
default = None
val = super(VmPortAddView, self).get_form_kwargs()
val.update({'choices': choices, 'default': default})
return val
class VmSaveView(FormOperationMixin, VmOperationView):
op = 'save_as_template'
......@@ -712,6 +704,7 @@ vm_ops = OrderedDict([
icon='times', effect="danger")),
('add_interface', VmAddInterfaceView),
('remove_port', VmPortRemoveView),
('add_port', VmPortAddView),
('renew', VmRenewView),
('resources_change', VmResourcesChangeView),
('password_reset', VmOperationView.factory(
......
......@@ -625,6 +625,24 @@ class RemovePortOperation(InstanceOperation):
@register_operation
class AddPortOperation(InstanceOperation):
id = 'add_port'
name = _("open port")
description = _("Open the specified port.")
concurrency_check = False
required_perms = ()
accept_states = ()
def _operation(self, activity, host, proto, port):
if host.interface_set.get().instance != self.instance:
raise PermissionDenied()
host.add_port(proto, private=port)
activity.readable_name = create_readable(
ugettext_noop("open %(proto)s/%(port)d on %(host)s"),
proto=proto, port=port, host=host)
@register_operation
class RemoveDiskOperation(InstanceOperation):
id = 'remove_disk'
name = _("remove disk")
......
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