Commit ac8ffba0 by Bach Dániel

fixes #116

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