Commit 883d6de6 by Őry Máté

Merge branch 'master' into acl

Conflicts:
	circle/circle/settings/base.py
parents e1b8a82b 97b69b04
"""Common settings and globals.""" """Common settings and globals."""
from datetime import timedelta
from os import environ from os import environ
from os.path import abspath, basename, dirname, join, normpath from os.path import abspath, basename, dirname, join, normpath
from json import loads from json import loads
# from socket import SOCK_STREAM # from socket import SOCK_STREAM
from sys import path from sys import path
# Normally you should not import ANYTHING from Django directly # Normally you should not import ANYTHING from Django directly
# into your settings, but ImproperlyConfigured is an exception. # into your settings, but ImproperlyConfigured is an exception.
from django.core.exceptions import ImproperlyConfigured from django.core.exceptions import ImproperlyConfigured
...@@ -311,3 +312,11 @@ AUTHENTICATION_BACKENDS = ( ...@@ -311,3 +312,11 @@ AUTHENTICATION_BACKENDS = (
'guardian.backends.ObjectPermissionBackend', 'guardian.backends.ObjectPermissionBackend',
) )
ANONYMOUS_USER_ID = -1 ANONYMOUS_USER_ID = -1
# Set up periodic firewall tasks
CELERYBEAT_SCHEDULE = {
'blabla': {
'task': 'firewall.tasks.local_tasks.periodic_task',
'schedule': timedelta(seconds=5),
},
}
from django_tables2 import Table, A from django_tables2 import Table, A
from django_tables2.columns import Column, LinkColumn, TemplateColumn from django_tables2.columns import LinkColumn, TemplateColumn
from vm.models import Instance from vm.models import Instance
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
class VmListTable(Table): class VmListTable(Table):
name = LinkColumn('dashboard.views.detail', args=[A('pk')]) pk = TemplateColumn(
admin = TemplateColumn(template_name='dashboard/vm-list/column-admin.html') template_name='dashboard/vm-list/column-id.html',
details = TemplateColumn(template_name= verbose_name="ID",
'dashboard/vm-list/column-details.html') attrs={'th': {'class': 'vm-list-table-thin'}},
actions = TemplateColumn(template_name= )
'dashboard/vm-list/column-actions.html') name = LinkColumn(
'dashboard.views.detail',
args=[A('pk')],
attrs={'class': 'real-link'}
)
admin = TemplateColumn(
template_name='dashboard/vm-list/column-admin.html',
attrs={'th': {'class': 'vm-list-table-admin'}},
)
details = TemplateColumn(
template_name='dashboard/vm-list/column-details.html',
attrs={'th': {'class': 'vm-list-table-thin'}},
)
actions = TemplateColumn(
template_name='dashboard/vm-list/column-actions.html',
attrs={'th': {'class': 'vm-list-table-thin'}},
)
time_of_suspend = TemplateColumn( time_of_suspend = TemplateColumn(
'{{ record.time_of_suspend|timesince }}', '{{ record.time_of_suspend|timeuntil }}',
verbose_name=_("Suspend in")) verbose_name=_("Suspend in"))
time_of_delete = Column(verbose_name=_("Delete in")) time_of_delete = TemplateColumn(
'{{ record.time_of_delete|timeuntil }}',
verbose_name=_("Delete in"))
class Meta: class Meta:
model = Instance model = Instance
......
...@@ -3,7 +3,8 @@ ...@@ -3,7 +3,8 @@
<label for="cpu-priority-slider"><i class="icon-trophy"></i> CPU priority</label> <label for="cpu-priority-slider"><i class="icon-trophy"></i> CPU priority</label>
</div> </div>
<div class="col-sm-9"> <div class="col-sm-9">
<input type="text" data-slider="true" data-slider-highlight="true" data-slider-snap="true" id="cpu-priority-slider" value="0.25"> <input type="text" data-slider="true" data-slider-highlight="true"
data-slider-snap="true" data-slider-range="0,100" data-slider-step="1" id="cpu-priority-slider" value="{{ instance.priority }}">
</div> </div>
</p> </p>
...@@ -13,7 +14,7 @@ ...@@ -13,7 +14,7 @@
<label for="cpu-count-slider"><i class="icon-cogs"></i> CPU count</label> <label for="cpu-count-slider"><i class="icon-cogs"></i> CPU count</label>
</div> </div>
<div class="col-sm-9"> <div class="col-sm-9">
<input type="text" value="1" data-slider="true" data-slider-highlight="true" data-slider-range="0,8" data-slider-snap="true" data-slider-step="1" id="cpu-count-slider"> <input type="text" value="{{ instance.num_cores }}" data-slider="true" data-slider-highlight="true" data-slider-range="0,8" data-slider-snap="true" data-slider-step="1" id="cpu-count-slider">
</div> </div>
</p> </p>
...@@ -23,7 +24,7 @@ ...@@ -23,7 +24,7 @@
<label for="ram-slider"><i class="icon-ticket"></i> RAM amount</label> <label for="ram-slider"><i class="icon-ticket"></i> RAM amount</label>
</div> </div>
<div class="col-sm-9"> <div class="col-sm-9">
<input type="text" data-slider="true" data-slider-highlight="true" id="ram-slider" data-slider-range="128,4096" data-slider-snap="true" data-slider-step="128"> MiB <input type="text" data-slider="true" data-slider-highlight="true" id="ram-slider" data-slider-range="128,4096" data-slider-snap="true" data-slider-step="128" value="{{ instance.ram_size }}"> MiB
</div> </div>
</p> </p>
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
<div class="row"> <div class="row">
<div class="col-md-4" id="vm-info-pane"> <div class="col-md-4" id="vm-info-pane">
<div class="big"> <div class="big">
<span class="label label-success ">RUNNING</span> <span class="label label-success">{{ instance.state }}</span>
<div class="btn-group"> <div class="btn-group">
<button type="button" class="btn btn-warning dropdown-toggle" data-toggle="dropdown">Action <i class="icon-caret-down"></i></button> <button type="button" class="btn btn-warning dropdown-toggle" data-toggle="dropdown">Action <i class="icon-caret-down"></i></button>
<ul class="dropdown-menu" role="menu"> <ul class="dropdown-menu" role="menu">
......
...@@ -4,7 +4,11 @@ ...@@ -4,7 +4,11 @@
{% block content %} {% block content %}
<div class="alert alert-info"> <div class="alert alert-info">
Tip of the day: you can select multiple vm instances while holding down the <strong>CTRL</strong> button! Tip #1: you can select multiple vm instances while holding down the <strong>CTRL</strong> key!
</div>
<div class="alert alert-info">
Tip #2: if you want to select multiple instances by one click select an instance then hold down <strong>SHIFT</strong> key and select another one!
</div> </div>
<div class="row"> <div class="row">
...@@ -13,6 +17,16 @@ ...@@ -13,6 +17,16 @@
<div class="panel-heading"> <div class="panel-heading">
<h3 class="no-margin"><i class="icon-desktop"></i> Your virtual machines</h3> <h3 class="no-margin"><i class="icon-desktop"></i> Your virtual machines</h3>
</div> </div>
<div class="panel-body vm-list-group-control">
<p>
<strong>Group actions</strong>
<button class="btn btn-info btn-xs" disabled>Select all</button>
<a class="btn btn-default btn-xs" id="vm-list-group-migrate" disabled><i class="icon-truck"></i> Migrate</a>
<a disabled href="#" class="btn btn-default btn-xs"><i class="icon-refresh"></i> Reboot</a>
<a disabled href="#" class="btn btn-default btn-xs"><i class="icon-off"></i> Shutdown</a>
<a disabled href="#" class="btn btn-danger btn-xs"><i class="icon-remove"></i> Discard</a>
</p>
</div>
<div class="panel-body"> <div class="panel-body">
<table class="table table-bordered table-striped table-hover vm-list-table"> <table class="table table-bordered table-striped table-hover vm-list-table">
<thead> <thead>
...@@ -71,27 +85,79 @@ ...@@ -71,27 +85,79 @@
.vm-list-selected td:first-child { .vm-list-selected td:first-child {
font-weight: bold; font-weight: bold;
} }
.vm-list-table-thin {
width: 10px;
}
.vm-list-table-admin {
width: 130px;
}
</style> </style>
{% endblock %} {% endblock %}
{% block extra_js %} {% block extra_js %}
$(function() { $(function() {
var ctrlDown = false; var ctrlDown, shiftDown = false;
var ctrlKey = 17; var ctrlKey = 17;
var shiftKey = 16;
var selected = [];
$(document).keydown(function(e) { $(document).keydown(function(e) {
if (e.keyCode == ctrlKey) ctrlDown = true; if (e.keyCode == ctrlKey) ctrlDown = true;
if (e.keyCode == shiftKey) shiftDown = true;
}).keyup(function(e) { }).keyup(function(e) {
if (e.keyCode == ctrlKey) ctrlDown = false; if (e.keyCode == ctrlKey) ctrlDown = false;
if (e.keyCode == shiftKey) shiftDown = false;
}); });
$('.vm-list-table').find('tr').click(function() { $('.vm-list-table tbody').find('tr').mousedown(function() {
if (ctrlDown) { if (ctrlDown) {
setRowColor($(this)); setRowColor($(this));
if(!$(this).hasClass('vm-list-selected')) {
selected.splice(selected.indexOf($(this).index()), 1);
} else {
selected.push($(this).index());
}
} else if(shiftDown) {
if(selected.length > 0) {
start = selected[selected.length - 1] + 1;
end = $(this).index();
if(start > end) {
var tmp = start - 1; start = end; end = tmp - 1;
}
for(var i = start; i <= end; i++) {
if(selected.indexOf(i) < 0) {
selected.push(i);
setRowColor($('.vm-list-table tbody tr').eq(i));
}
}
}
} else { } else {
$('.vm-list-selected').removeClass('vm-list-selected'); $('.vm-list-selected').removeClass('vm-list-selected');
$(this).addClass('vm-list-selected'); $(this).addClass('vm-list-selected');
selected = [$(this).index()];
} }
// reset btn disables
$('.vm-list-table tbody tr .btn').attr('disabled', false);
// show/hide group controls
if(selected.length > 1) {
$('.vm-list-group-control .btn').attr('disabled', false);
for(var i = 0; i < selected.length; i++) {
$('.vm-list-table tbody tr').eq(selected[i]).find('.btn').attr('disabled', true);
}
} else {
$('.vm-list-group-control .btn').attr('disabled', true);
}
return false;
});
$('#vm-list-group-migrate').click(function() {
console.log(collectIds(selected));
}); });
$('.vm-list-details').popover({ $('.vm-list-details').popover({
...@@ -106,25 +172,28 @@ $(function() { ...@@ -106,25 +172,28 @@ $(function() {
'trigger': 'click' 'trigger': 'click'
}); });
/* $('tbody a').mousedown(function(e) {
$('#check_all').click(function() { // parent tr doesn't get selected when clicked
var checked = $(this).prop('checked'); e.stopPropagation();
$('.vm-checkbox').each(function() { });
// reverse
// $(this).prop('checked', !$(this).prop('checked'));
// set
$(this).prop('checked', checked);
setRowColor($(this))
})
});
$('.vm-checkbox').click(function() { $('tbody a').click(function(e) {
setRowColor($(this)); // browser doesn't jump to top when clicked the buttons
if(!$(this).hasClass('real-link')) {
return false;
}
}); });
*/
}); });
function collectIds(rows) {
var ids = [];
for(var i = 0; i < rows.length; i++) {
var div = $('td:first-child div', $('.vm-list-table tbody tr').eq(rows[i]));
ids.push(div.prop('id').replace('vm-', ''));
}
return ids;
}
function setRowColor(row) { function setRowColor(row) {
if(!row.hasClass('vm-list-selected')) { if(!row.hasClass('vm-list-selected')) {
......
sziahello
<div class="btn-group">
<button type="button" class="btn btn-xs btn-warning dropdown-toggle" data-toggle="dropdown">Action <i class="icon-caret-down"></i></button>
<ul class="dropdown-menu" role="menu">
<li><a href="#"><i class="icon-refresh"></i> Reboot</a></li>
<li><a href="#"><i class="icon-off"></i> Shutdown</a></li>
<li><a href="#"><i class="icon-remove"></i> Discard</a></li>
</ul>
</div>
admin
<a class="btn btn-default btn-xs" title data-original-title="Migrate">
<i class="icon-truck"></i>
</a>
<a class="btn btn-default btn-xs" title data-original-title="Rename">
<i class="icon-pencil"></i>
</a>
<a href="#" class="btn btn-default btn-xs vm-list-connect" data-toggle="popover"
data-content='
Belépés: <input style="width: 300px;" type="text" class="form-control" value="ssh cloud@vm.ik.bme.hu -p22312"/>
Jelszó: <input style="width: 300px;" type="text" class="form-control" value="asdfkicsiasdfkocsi"/>
'>Connect</a>
detail <a class="btn btn-info btn-xs vm-list-details" href="#" data-toggle="popover"
data-content='
<h4>Quick details</h4>
<dl class="dl-horizontal">
<dt>Number of cores:</dt><dd>{{ record.num_cores }}</dd>
<dt>Memory:</dt> <dd>{{ record.ram_size }} Mebibytes</dd>
<dt>Architecture:</td><dd>{{ record.arch }}</dd>
</dl>
<dl>
<dt>IPv4 address:</dt><dd>{{ record.ipv4 }}10.9.8.7</dd>
<dt>IPv6 address:</dt><dd> 2001:2001:2001:2001:2001:2001::</dd>
<dt>DNS name:</dt><dd>1825.vm.ik.bme.hu</dd>
</ul>
'>Details</a>
<div id="vm-{{ record.pk }}">{{ record.pk }}</div>
<tr> <tr>
<!--<td><input type="checkbox"/ class="vm-checkbox" id="vm-1825{{ c }}"></td>--> <!--<td><input type="checkbox"/ class="vm-checkbox" id="vm-1825{{ c }}"></td>-->
<td>182{{ c }}</td> <td>
<td><a href="">network-devenv</a></td> <div id="vm-1{{ c }}">1{{ c }}</div>
</td>
<td><a href="" class="real-link">network-devenv</a></td>
<td>running</td> <td>running</td>
<td>10 days</td> <td>10 days</td>
<td>1 month</td> <td>1 month</td>
<td> <td>
<span class="btn btn-default btn-xs" title data-original-title="Migrate"> <a class="btn btn-default btn-xs" title data-original-title="Migrate">
<i class="icon-truck"></i> <i class="icon-truck"></i>
</span> </a>
<span class="btn btn-default btn-xs" title data-original-title="Rename"> <a class="btn btn-default btn-xs" title data-original-title="Rename">
<i class="icon-pencil"></i> <i class="icon-pencil"></i>
</span> </a>
<a href="#" class="btn btn-default btn-xs vm-list-connect" data-toggle="popover" <a href="#" class="btn btn-default btn-xs vm-list-connect" data-toggle="popover"
data-content=' data-content='
Belépés: <input style="width: 300px;" type="text" class="form-control" value="ssh cloud@vm.ik.bme.hu -p22312"/> Belépés: <input style="width: 300px;" type="text" class="form-control" value="ssh cloud@vm.ik.bme.hu -p22312"/>
......
...@@ -74,3 +74,4 @@ class VmList(SingleTableView): ...@@ -74,3 +74,4 @@ class VmList(SingleTableView):
template_name = "dashboard/vm-list.html" template_name = "dashboard/vm-list.html"
model = Instance model = Instance
table_class = VmListTable table_class = VmListTable
table_pagination = False
...@@ -49,7 +49,7 @@ class RuleAdmin(admin.ModelAdmin): ...@@ -49,7 +49,7 @@ class RuleAdmin(admin.ModelAdmin):
list_display = ('r_type', 'color_desc', 'owner', 'extra', 'direction', list_display = ('r_type', 'color_desc', 'owner', 'extra', 'direction',
'accept', 'proto', 'sport', 'dport', 'nat', 'accept', 'proto', 'sport', 'dport', 'nat',
'nat_dport', 'used_in') 'nat_dport', 'used_in')
list_filter = ('r_type', 'vlan', 'owner', 'direction', 'accept', list_filter = ('vlan', 'owner', 'direction', 'accept',
'proto', 'nat') 'proto', 'nat')
def color_desc(self, instance): def color_desc(self, instance):
......
...@@ -64,7 +64,7 @@ class IPNetworkField(models.Field): ...@@ -64,7 +64,7 @@ class IPNetworkField(models.Field):
description = _('IP Network object') description = _('IP Network object')
__metaclass__ = models.SubfieldBase __metaclass__ = models.SubfieldBase
def __init__(self, version=4, *args, **kwargs): def __init__(self, version=4, serialize=True, *args, **kwargs):
kwargs['max_length'] = 100 kwargs['max_length'] = 100
self.version = version self.version = version
super(IPNetworkField, self).__init__(*args, **kwargs) super(IPNetworkField, self).__init__(*args, **kwargs)
...@@ -98,7 +98,7 @@ class IPNetworkField(models.Field): ...@@ -98,7 +98,7 @@ class IPNetworkField(models.Field):
def value_to_string(self, obj): def value_to_string(self, obj):
value = self._get_val_from_obj(obj) value = self._get_val_from_obj(obj)
return self.get_prep_value(value) return str(self.get_prep_value(value))
def clean(self, value, model_instance): def clean(self, value, model_instance):
value = super(IPNetworkField, self).clean(value, model_instance) value = super(IPNetworkField, self).clean(value, model_instance)
......
from firewall import models from firewall import models
import django.conf import django.conf
import subprocess
import re import re
from datetime import datetime, timedelta from datetime import datetime, timedelta
from django.db.models import Q from django.db.models import Q
...@@ -12,14 +10,6 @@ settings = django.conf.settings.FIREWALL_SETTINGS ...@@ -12,14 +10,6 @@ settings = django.conf.settings.FIREWALL_SETTINGS
class Firewall: class Firewall:
IPV6 = False
RULES = None
RULES_NAT = []
vlans = None
pub = None
hosts = None
fw = None
def dportsport(self, rule, repl=True): def dportsport(self, rule, repl=True):
retval = ' ' retval = ' '
if rule.proto == 'tcp' or rule.proto == 'udp': if rule.proto == 'tcp' or rule.proto == 'udp':
...@@ -46,7 +36,7 @@ class Firewall: ...@@ -46,7 +36,7 @@ class Firewall:
if not rule.foreign_network: if not rule.foreign_network:
return return
if self.IPV6 and host.ipv6: if self.proto == 6 and host.ipv6:
ipaddr = host.ipv6 + '/112' ipaddr = host.ipv6 + '/112'
else: else:
ipaddr = host.ipv4 ipaddr = host.ipv4
...@@ -156,10 +146,6 @@ class Firewall: ...@@ -156,10 +146,6 @@ class Firewall:
'-j ACCEPT') '-j ACCEPT')
def postrun(self): def postrun(self):
self.iptables('-A PUB_OUT -s 152.66.243.160/27 -p tcp --dport 25 '
'-j LOG_ACC')
self.iptables('-A PUB_OUT -s 152.66.243.160/27 -p tcp --dport 445 '
'-j LOG_ACC')
self.iptables('-A PUB_OUT -p tcp --dport 25 -j LOG_DROP') self.iptables('-A PUB_OUT -p tcp --dport 25 -j LOG_DROP')
self.iptables('-A PUB_OUT -p tcp --dport 445 -j LOG_DROP') self.iptables('-A PUB_OUT -p tcp --dport 445 -j LOG_DROP')
self.iptables('-A PUB_OUT -p udp --dport 445 -j LOG_DROP') self.iptables('-A PUB_OUT -p udp --dport 445 -j LOG_DROP')
...@@ -206,15 +192,6 @@ class Firewall: ...@@ -206,15 +192,6 @@ class Firewall:
(str(s_vlan.network4), d_vlan.interface, (str(s_vlan.network4), d_vlan.interface,
s_vlan.snat_ip)) s_vlan.snat_ip))
# hard-wired rules
self.iptablesnat('-A POSTROUTING -s 10.5.0.0/16 -o vlan0003 -j SNAT '
'--to-source 10.3.255.254') # man elerheto legyen
self.iptablesnat('-A POSTROUTING -o vlan0008 -j SNAT '
'--to-source 10.0.0.247') # wolf network for printing
self.iptablesnat('-A POSTROUTING -s 10.3.0.0/16 -p udp --dport 53 '
'-o vlan0002 -j SNAT ''--to-source %s' %
self.pub.ipv4) # kulonben nem megy a dns man-ban
self.iptablesnat('COMMIT') self.iptablesnat('COMMIT')
def ipt_filter(self): def ipt_filter(self):
...@@ -258,45 +235,29 @@ class Firewall: ...@@ -258,45 +235,29 @@ class Firewall:
# post-run stuff # post-run stuff
self.postrun() self.postrun()
if self.IPV6: if self.proto == 6:
self.RULES = [x for x in self.RULES if not ipv4_re.search(x)] self.RULES = [x for x in self.RULES if not ipv4_re.search(x)]
self.RULES = [x.replace('icmp', 'icmpv6') for x in self.RULES] self.RULES = [x.replace('icmp', 'icmpv6') for x in self.RULES]
def __init__(self, IPV6=False): def __init__(self, proto=4):
self.RULES = [] self.RULES = []
self.RULES_NAT = [] self.RULES_NAT = []
self.IPV6 = IPV6 self.proto = proto
self.vlans = models.Vlan.objects.all() self.vlans = models.Vlan.objects.all()
self.hosts = models.Host.objects.all() self.hosts = models.Host.objects.all()
self.pub = models.Vlan.objects.get(name='PUB')
self.fw = models.Firewall.objects.all() self.fw = models.Firewall.objects.all()
self.ipt_filter() self.ipt_filter()
if not self.IPV6: if self.proto != 6:
self.ipt_nat() self.ipt_nat()
def reload(self):
if self.IPV6:
process = subprocess.Popen(['/usr/bin/ssh', 'fw2',
'/usr/bin/sudo',
'/sbin/ip6tables-restore', '-c'],
shell=False, stdin=subprocess.PIPE)
process.communicate('\n'.join(self.RULES) + '\n')
else:
process = subprocess.Popen(['/usr/bin/ssh', 'fw2',
'/usr/bin/sudo',
'/sbin/iptables-restore', '-c'],
shell=False, stdin=subprocess.PIPE)
process.communicate('\n'.join(self.RULES) + '\n' +
'\n'.join(self.RULES_NAT) + '\n')
def get(self): def get(self):
if self.IPV6: if self.proto == 6:
return {'filter': self.RULES, } return {'filter': self.RULES, }
else: else:
return {'filter': self.RULES, 'nat': self.RULES_NAT} return {'filter': self.RULES, 'nat': self.RULES_NAT}
def show(self): def show(self):
if self.IPV6: if self.proto == 6:
return '\n'.join(self.RULES) + '\n' return '\n'.join(self.RULES) + '\n'
else: else:
return ('\n'.join(self.RULES) + '\n' + return ('\n'.join(self.RULES) + '\n' +
...@@ -413,11 +374,6 @@ def dns(): ...@@ -413,11 +374,6 @@ def dns():
DNS.append("^%s:%s:%s" % (d['name'], d['address'], d['ttl'])) DNS.append("^%s:%s:%s" % (d['name'], d['address'], d['ttl']))
return DNS return DNS
process = subprocess.Popen(['/usr/bin/ssh', 'tinydns@%s' %
settings['dns_hostname']],
shell=False, stdin=subprocess.PIPE)
process.communicate("\n".join(DNS) + "\n")
# print "\n".join(DNS)+"\n"
def prefix_to_mask(prefix): def prefix_to_mask(prefix):
...@@ -480,9 +436,11 @@ def dhcp(): ...@@ -480,9 +436,11 @@ def dhcp():
}) })
return DHCP return DHCP
process = subprocess.Popen(['/usr/bin/ssh', 'fw2',
'cat > /tools/dhcp3/dhcpd.conf.generated;'
'sudo /etc/init.d/isc-dhcp-server restart'], def vlan():
shell=False, stdin=subprocess.PIPE) obj = models.Vlan.objects.values('vid', 'name', 'network4', 'network6')
# print "\n".join(DHCP)+"\n" return {x['name']: {'tag': x['vid'],
process.communicate("\n".join(DHCP) + "\n") 'addresses': [str(x['network4']),
str(x['network6'])]}
for x in obj}
...@@ -12,6 +12,7 @@ import django.conf ...@@ -12,6 +12,7 @@ import django.conf
from django.db.models.signals import post_save from django.db.models.signals import post_save
import random import random
from firewall.tasks.local_tasks import reloadtask
settings = django.conf.settings.FIREWALL_SETTINGS settings = django.conf.settings.FIREWALL_SETTINGS
...@@ -62,10 +63,6 @@ class Rule(models.Model): ...@@ -62,10 +63,6 @@ class Rule(models.Model):
verbose_name=_("owner"), verbose_name=_("owner"),
help_text=_("The user responsible for " help_text=_("The user responsible for "
"this rule.")) "this rule."))
r_type = models.CharField(max_length=10, verbose_name=_("Rule type"),
choices=CHOICES_type,
help_text=_("The type of entity the rule "
"belongs to."))
nat = models.BooleanField(default=False, verbose_name=_("NAT"), nat = models.BooleanField(default=False, verbose_name=_("NAT"),
help_text=_("If network address translation " help_text=_("If network address translation "
"shoud be done.")) "shoud be done."))
...@@ -129,6 +126,15 @@ class Rule(models.Model): ...@@ -129,6 +126,15 @@ class Rule(models.Model):
(("dport=%s " % self.dport) if self.dport else '')), (("dport=%s " % self.dport) if self.dport else '')),
'desc': self.description} 'desc': self.description}
@property
def r_type(self):
fields = [self.vlan, self.vlangroup, self.host, self.hostgroup,
self.firewall]
for field in fields:
if field is not None:
return field.__class__.__name__.lower()
return None
@models.permalink @models.permalink
def get_absolute_url(self): def get_absolute_url(self):
return ('network.rule', None, {'pk': self.pk}) return ('network.rule', None, {'pk': self.pk})
...@@ -137,7 +143,6 @@ class Rule(models.Model): ...@@ -137,7 +143,6 @@ class Rule(models.Model):
verbose_name = _("rule") verbose_name = _("rule")
verbose_name_plural = _("rules") verbose_name_plural = _("rules")
ordering = ( ordering = (
'r_type',
'direction', 'direction',
'proto', 'proto',
'sport', 'sport',
...@@ -278,6 +283,24 @@ class Vlan(models.Model): ...@@ -278,6 +283,24 @@ class Vlan(models.Model):
def prefix6(self): def prefix6(self):
return self.network6.prefixlen return self.network6.prefixlen
def get_new_address(self):
i = 0
hosts = Host.objects.filter(vlan=self)
used_v4 = hosts.values_list('ipv4', flat=True)
used_v6 = hosts.values_list('ipv6', flat=True)
for ipv4 in self.network4.iter_hosts():
i += 1
if i > 10000:
break
ipv4 = str(ipv4)
if ipv4 not in used_v4:
print ipv4
ipv6 = ipv4_2_ipv6(ipv4)
if ipv6 not in used_v6:
return {'ipv4': ipv4, 'ipv6': ipv6}
raise ValidationError(_("All IP addresses are already in use."))
class VlanGroup(models.Model): class VlanGroup(models.Model):