Commit ac8ffba0 by Bach Dániel

fixes #116

parent 6625e283
......@@ -37,7 +37,7 @@ urlpatterns = patterns('',
url(r'^vm/renew/(?P<which>(suspend|delete))/(?P<iid>\d+)/$',
'one.views.vm_renew', ),
url(r'^vm/port_add/(?P<iid>\d+)/$', 'one.views.vm_port_add', ),
url(r'^vm/port_del/(?P<iid>\d+)/(?P<proto>tcp|udp)/(?P<public>\d+)/$',
url(r'^vm/port_del/(?P<iid>\d+)/(?P<proto>tcp|udp)/(?P<private>\d+)/$',
'one.views.vm_port_del', ),
url(r'^ajax/shareEdit/(?P<id>\d+)/$', 'one.views.ajax_share_edit_wizard',
name='ajax_share_edit_wizard'),
......
......@@ -174,15 +174,30 @@ class Host(models.Model):
def enable_net(self):
self.groups.add(Group.objects.get(name="netezhet"))
def add_port(self, proto, public, private = 0):
def add_port(self, proto, public=None, private=None):
proto = "tcp" if proto == "tcp" else "udp"
if self.shared_ip:
if public < 1024:
raise ValidationError(_("Only ports above 1024 can be used."))
for host in Host.objects.filter(pub_ipv4=self.pub_ipv4):
if host.rules.filter(nat=True, proto=proto, dport=public):
used_ports = Rule.objects.filter(host__pub_ipv4=self.pub_ipv4,
nat=True, proto=proto).values_list('dport', flat=True)
if public is None:
public = random.randint(1024, 21000)
if public in used_ports:
for i in range(1024, 21000) + range(24000, 65535):
if i not in used_ports:
public = i
break
else:
raise ValidationError(_("Port %s %s is already in use.") %
(proto, public))
else:
if public < 1024:
raise ValidationError(_("Only ports above 1024 can be used."))
if public in used_ports:
raise ValidationError(_("Port %s %s is already in use.") %
(proto, public))
rule = Rule(direction='1', owner=self.owner, dport=public,
proto=proto, nat=True, accept=True, r_type="host",
nat_dport=private, host=self, foreign_network=VlanGroup.
......@@ -199,15 +214,58 @@ class Host(models.Model):
rule.full_clean()
rule.save()
def del_port(self, proto, public):
self.rules.filter(owner=self.owner, proto=proto, host=self,
dport=public).delete()
def del_port(self, proto, private):
if self.shared_ip:
self.rules.filter(owner=self.owner, proto=proto, host=self,
nat_dport=private).delete()
else:
self.rules.filter(owner=self.owner, proto=proto, host=self,
dport=private).delete()
def get_hostname(self, proto):
try:
if proto == 'ipv6':
res = self.record_set.filter(type='AAAA')
elif proto == 'ipv4':
if self.shared_ip:
res = Record.objects.filter(type='A',
address=self.pub_ipv4)
else:
res = self.record_set.filter(type='A')
return unicode(res[0].get_data()['name'])
except:
raise
if self.shared_ip:
return self.pub_ipv4
else:
return self.ipv4
def list_ports(self):
return [{'proto': rule.proto,
'public': rule.dport,
'private': rule.nat_dport} for rule in
self.rules.filter(owner=self.owner)]
retval = []
for rule in self.rules.filter(owner=self.owner):
private = rule.nat_dport if self.shared_ip else rule.dport
forward = {
'proto': rule.proto,
'private': private,
}
if self.shared_ip:
public4 = rule.dport
public6 = rule.nat_dport
else:
public4 = public6 = rule.dport
if True: # ipv4
forward['ipv4'] = {
'host': self.get_hostname(proto='ipv4'),
'port': public4,
}
if self.ipv6: # ipv6
forward['ipv6'] = {
'host': self.get_hostname(proto='ipv6'),
'port': public6,
}
retval.append(forward)
return retval
def get_fqdn(self):
return self.hostname + u'.' + unicode(self.vlan.domain)
......
......@@ -433,24 +433,13 @@ class Instance(models.Model):
return {"rdp": 23000, "nx": 22000, "ssh": 22000}[proto] + int(self.ip.split('.')[2]) * 256 + int(self.ip.split('.')[3])
else:
return {"rdp": 3389, "nx": 22, "ssh": 22}[proto]
def get_connect_host(self, use_ipv6=False):
"""Get public hostname."""
if self.firewall_host is None:
return _('None')
try:
if use_ipv6:
return self.firewall_host.record_set.filter(type='AAAA')[0].get_data()['name']
else:
if self.template.network.nat:
ip = self.firewall_host.pub_ipv4
return Record.objects.filter(type='A', address=ip)[0].get_data()['name']
else:
return self.firewall_host.record_set.filter(type='A')[0].get_data()['name']
except:
if self.template.network.nat:
return self.firewall_host.pub_ipv4
else:
return self.firewall_host.ipv4
proto = 'ipv6' if use_ipv6 else 'ipv4'
return self.firewall_host.get_hostname(proto=proto)
def get_connect_uri(self, use_ipv6=False):
"""Get access parameters in URI format."""
......
......@@ -163,7 +163,7 @@
{% endif %}
</td>
<td>
<a href="{% url one.views.vm_port_del i.id port.proto port.public %}">{% trans "Delete" %}</a>
<a href="{% url one.views.vm_port_del i.id port.proto port.private %}">{% trans "Delete" %}</a>
</td>
</tr>
<tr>
......@@ -182,7 +182,7 @@
{% endif %}
</td>
<td>
<a href="{% url one.views.vm_port_del i.id port.proto port.public %}">{% trans "Delete" %}</a>
<a href="{% url one.views.vm_port_del i.id port.proto port.private %}">{% trans "Delete" %}</a>
</td>
</tr>
{% endfor %}
......@@ -198,7 +198,7 @@
</select>
</td>
<td>
<input style="min-width:70px;width:70px;" type="text" name="public"/>
<input style="min-width:70px;width:70px;" type="text" name="port"/>
</td>
<td>
<input type="submit" style="min-width:3em" value="{% trans "Add" %}" />
......
......@@ -423,20 +423,20 @@ def boot_token(request, token):
class VmPortAddView(View):
def post(self, request, iid, *args, **kwargs):
try:
public = int(request.POST['public'])
if public >= 22000 and public < 24000:
raise ValidationError(_("Port number is in a restricted domain (22000 to 24000)."))
port = int(request.POST['port'])
inst = get_object_or_404(Instance, id=iid, owner=request.user)
if inst.template.network.nat:
private = private=int(request.POST['private'])
if inst.firewall_host.shared_ip:
inst.firewall_host.add_port(proto=request.POST['proto'],
public=None, private=port)
else:
private = 0
inst.firewall_host.add_port(proto=request.POST['proto'], public=public, private=private)
messages.success(request, _(u"Port %d successfully added.") % public)
inst.firewall_host.add_port(proto=request.POST['proto'],
public=private, private=None)
except:
messages.error(request, _(u"Adding port failed."))
# raise
raise
else:
messages.success(request, _(u"Port %d successfully added.") % port)
return redirect('/vm/show/%d/' % int(iid))
def get(self, request, iid, *args, **kwargs):
......@@ -447,11 +447,12 @@ vm_port_add = login_required(VmPortAddView.as_view())
@require_safe
@login_required
@require_GET
def vm_port_del(request, iid, proto, public):
def vm_port_del(request, iid, proto, private):
inst = get_object_or_404(Instance, id=iid, owner=request.user)
try:
inst.firewall_host.del_port(proto=proto, public=public)
messages.success(request, _(u"Port %s successfully removed.") % public)
inst.firewall_host.del_port(proto=proto, private=private)
messages.success(request, _(u"Port %s successfully removed.") %
private)
except:
messages.error(request, _(u"Removing port failed."))
return redirect('/vm/show/%d/' % int(iid))
......
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