Commit 857316e0 by Kálmán Viktor

Merge branch 'issue-378' into 'master'

Firewall model to network GUI 

closes #378

See merge request !290
parents 9e28c78c ffa98f10
......@@ -33,6 +33,7 @@ from firewall.fields import (MACAddressField, val_alfanum, val_reverse_domain,
val_ipv6, val_mx,
IPNetworkField, IPAddressField)
from django.core.validators import MinValueValidator, MaxValueValidator
from django.core.urlresolvers import reverse
import django.conf
from django.db.models.signals import post_save, post_delete
from celery.exceptions import TimeoutError
......@@ -191,9 +192,8 @@ class Rule(models.Model):
return field.__class__.__name__.lower()
return None
@models.permalink
def get_absolute_url(self):
return ('network.rule', None, {'pk': self.pk})
return reverse('network.rule', kwargs={'pk': self.pk})
def get_chain_name(self, local, remote):
if local: # host or vlan
......@@ -476,9 +476,8 @@ class Vlan(AclBase, models.Model):
return "%s - %s" % ("managed" if self.managed else "unmanaged",
self.name)
@models.permalink
def get_absolute_url(self):
return ('network.vlan', None, {'vid': self.vid})
return reverse('network.vlan', kwargs={'vid': self.vid})
def get_random_addresses(self, used_v4, buffer_size=100, max_hosts=10000):
addresses = islice(self.network4.iter_hosts(), max_hosts)
......@@ -544,9 +543,8 @@ class VlanGroup(models.Model):
def __unicode__(self):
return self.name
@models.permalink
def get_absolute_url(self):
return ('network.vlan_group', None, {'pk': self.pk})
return reverse('network.vlan_group', kwargs={'pk': self.pk})
class Group(models.Model):
......@@ -567,9 +565,8 @@ class Group(models.Model):
def __unicode__(self):
return self.name
@models.permalink
def get_absolute_url(self):
return ('network.group', None, {'pk': self.pk})
return reverse('network.group', kwargs={'pk': self.pk})
class Host(models.Model):
......@@ -919,9 +916,8 @@ class Host(models.Model):
endpoints['ipv6'] = (self.ipv6, port) if public_port else None
return endpoints
@models.permalink
def get_absolute_url(self):
return ('network.host', None, {'pk': self.pk})
return reverse('network.host', kwargs={'pk': self.pk})
@property
def eui(self):
......@@ -970,6 +966,9 @@ class Firewall(models.Model):
logger.exception("get_dhcp_clients failed")
return {}
def get_absolute_url(self):
return reverse('network.firewall', kwargs={'pk': self.pk})
class Domain(models.Model):
name = models.CharField(max_length=40, validators=[val_domain],
......@@ -985,9 +984,8 @@ class Domain(models.Model):
def __unicode__(self):
return self.name
@models.permalink
def get_absolute_url(self):
return ('network.domain', None, {'pk': self.pk})
return reverse('network.domain', kwargs={'pk': self.pk})
class Record(models.Model):
......@@ -1056,9 +1054,8 @@ class Record(models.Model):
else:
return self.domain.name
@models.permalink
def get_absolute_url(self):
return ('network.record', None, {'pk': self.pk})
return reverse('network.record', kwargs={'pk': self.pk})
class Meta:
ordering = (
......@@ -1088,9 +1085,8 @@ class SwitchPort(models.Model):
self.untagged_vlan,
tagged_vlans)
@models.permalink
def get_absolute_url(self):
return ('network.switch_port', None, {'pk': self.pk})
return reverse('network.switch_port', kwargs={'pk': self.pk})
class EthernetDevice(models.Model):
......@@ -1143,9 +1139,8 @@ class BlacklistItem(models.Model):
verbose_name = _('blacklist item')
verbose_name_plural = _('blacklist')
@models.permalink
def get_absolute_url(self):
return ('network.blacklist', None, {'pk': self.pk})
return reverse('network.blacklist', kwargs={'pk': self.pk})
def send_task(sender, instance, created=False, **kwargs):
......
......@@ -23,8 +23,10 @@ from crispy_forms.helper import FormHelper
from crispy_forms.layout import Layout, Fieldset, Div, Submit, BaseInput
from crispy_forms.bootstrap import FormActions, FieldWithButtons, StrictButton
from firewall.models import (Host, Vlan, Domain, Group, Record, BlacklistItem,
Rule, VlanGroup, SwitchPort)
from firewall.models import (
Host, Vlan, Domain, Group, Record, BlacklistItem, Rule, VlanGroup,
SwitchPort, Firewall
)
class LinkButton(BaseInput):
......@@ -88,6 +90,21 @@ class DomainForm(ModelForm):
model = Domain
class FirewallForm(ModelForm):
helper = FormHelper()
helper.layout = Layout(
Div(Fieldset('', 'name', )),
FormActions(
Submit('submit', _("Save")),
LinkButton('back', _("Back"),
reverse_lazy('network.firewall_list'))
)
)
class Meta:
model = Firewall
class GroupForm(ModelForm):
helper = FormHelper()
helper.layout = Layout(
......
......@@ -12,6 +12,23 @@
width: 60px;
}
body {
padding-top: 40px;
}
/* note: this doesn't really work */
a i:hover {
text-decoration: none;
}
footer {
margin-top: 45px;
}
.messagelist {
margin-top: 25px;
}
#rule-list-table {
td {
text-align: center;
......
......@@ -245,3 +245,37 @@ class HostRecordsTable(Table):
fields = ("type", "fqdn")
order_by = ("name", )
empty_text = _("No records.")
class FirewallTable(Table):
pk = LinkColumn('network.firewall', args=[A('pk')],
verbose_name="ID")
class Meta:
model = SwitchPort
attrs = {'class': 'table table-striped'}
fields = ('pk', 'name', )
order_by = 'pk'
class FirewallRuleTable(Table):
color_desc = TemplateColumn(
template_name="network/columns/rule-short-description.html",
verbose_name=_("Short description"),
orderable=False,
)
actions = TemplateColumn(
template_name="network/columns/firewall-rule-actions.html",
verbose_name=_("Actions"),
orderable=False,
)
class Meta:
model = Rule
template = "django_tables2/table_no_page.html"
attrs = {'class': 'table table-striped table-hover table-condensed',
'id': "rule-list-table"}
fields = ('color_desc', 'extra', 'direction',
'action', 'proto', 'actions')
order_by = '-pk'
empty_text = _("No related rules found.")
......@@ -6,32 +6,6 @@
{% block title-site %}{% trans "Network" %} | CIRCLE{% endblock %}
{% block extra_link %}
<link href='//fonts.googleapis.com/css?family=Source+Sans+Pro:200,400&amp;subset=latin,latin-ext' rel='stylesheet' type='text/css'>
<link href="{% static "network/network.css" %}" rel="stylesheet">
{% endblock %}
{% block extra_css %}
<style type="text/css">
body {
padding-top:40px;
}
/* note: this doesn't really work */
a i:hover {
text-decoration: none;
}
footer {
margin-top: 45px;
}
.messagelist {
margin-top: 25px;
}
</style>
{% endblock %}
{% block navbar-brand %}
<a class="navbar-brand" href="{% url "network.index" %}">CIRCLE Network</a>
{% endblock %}
......
{% load i18n %}
<div style="white-space: nowrap;">
<a href="{% url "network.rule_delete" pk=record.pk %}?next={{ request.path }}"><i class="fa fa-times"></i></a>
<a href="{% url "network.rule" pk=record.pk %}"><i class="fa fa-pencil"></i></a>
</div>
{% load i18n %}
{% load l10n %}
<div style="white-space: nowrap;">
<a href="{% url "network.rule_delete" pk=record.pk %}?from={{ request.path }}"><i class="fa fa-times"></i></a>
<a href="{% url "network.rule_delete" pk=record.pk %}?next={{ request.path }}"><i class="fa fa-times"></i></a>
<a href="{% url "network.rule" pk=record.pk %}"><i class="fa fa-pencil"></i></a>
</div>
......@@ -31,7 +31,7 @@
</div>
{% endif %}
<form action="" method="post">{% csrf_token %}
<input type="hidden" value="{{ request.GET.from }}" name="next" />
<input type="hidden" value="{{ request.GET.next }}" name="next" />
{% if confirmation %}
<label><p>
{% trans "If you are really sure, type in the object's name!" %}
......
{% extends "network/base.html" %}
{% load i18n %}
{% load staticfiles %}
{% load crispy_forms_tags %}
{% block title-page %}{% trans "Create" %} | {% trans "firewall" %}{% endblock %}
{% block content %}
<div class="page-header">
<h2>{% trans "Create a new firewall" %}</h2>
</div>
<div class="row">
<div class="col-sm-8">
{% crispy form %}
</div>
</div>
{% endblock %}
{% extends "network/base.html" %}
{% load render_table from django_tables2 %}
{% load i18n %}
{% load staticfiles %}
{% load crispy_forms_tags %}
{% block title-page %}{{ object.name }} | {% trans "firewall" %}{% endblock %}
{% block content %}
<div class="page-header">
<a href="{% url "network.firewall_delete" pk=object.pk %}" class="btn btn-danger pull-right">
<i class="fa fa-times-circle"></i> {% trans "Delete this firewall" %}
</a>
<h2>{{ object.name }}</h2>
</div>
<div class="row">
<div class="col-sm-5">
{% crispy form %}
</div>
</div>
<div class="page-header">
<h2>{% trans "Related rules" %}</h2>
</div>
<div class="row">
<div class="col-sm-12">
{% render_table rule_table %}
</div>
</div>
{% endblock %}
{% extends "network/base.html" %}
{% load render_table from django_tables2 %}
{% load i18n %}
{% load l10n %}
{% load staticfiles %}
{% block title-page %}{% trans "Firewalls" %}{% endblock %}
{% block content %}
<div class="page-header">
<a href="{% url "network.firewall_create" %}" class="btn btn-success pull-right">
<i class="fa fa-plus-circle"></i> {% trans "Create a new firewall" %}
</a>
<h1>{% trans "Firewalls" %}</h1>
</div>
<div class="table-responsive">
{% render_table table %}
</div>
{% endblock %}
......@@ -35,7 +35,7 @@
{% for group in group_rule_list %}
<div>
<h4 id="{{ group.pk }}_group_pk">{{ group.name }}
<a href="{% url "network.remove_host_group" pk=host_pk group_pk=group.pk %}?from={{ request.path }}">
<a href="{% url "network.remove_host_group" pk=host_pk group_pk=group.pk %}?next={{ request.path }}">
<i class="fa fa-times" style="vertical-align: middle;"></i></a>
<a href="{% url "network.group" group.pk %}">
<i class="fa fa-pencil" style="vertical-align: middle;"></i></a>
......
......@@ -22,6 +22,9 @@
{% url "network.switch_port_list" as u %}
{% trans "Switch ports" as t %}
{% include "network/menu-item.html" with href=u text=t %}
{% url "network.firewall_list" as u %}
{% trans "Firewalls" as t %}
{% include "network/menu-item.html" with href=u text=t %}
<li class="dropdown{% if "groups" in request.path %} active{% endif %}">
<a href="#" class="dropdown-toggle" data-toggle="dropdown">Groups <b class="caret"></b></a>
......@@ -35,12 +38,3 @@
{% include "network/menu-item.html" with href=u text=t %}
</ul>
</li>
{# <li><a href="/vlans/">{% trans "Vlans" %}</a></li> #}
{# <li><a href="/vlangroups/">{% trans "Vlan groups" %}</a></li> #}
{# <li><a href="/hostgroups/">{% trans "Host groups" %}</a></li> #}
{# <li><a href="/hosts/">{% trans "Hosts" %}</a></li> #}
{# <li><a href="/firewalls/">{% trans "Firewalls" %}</a></li> #}
{# <li><a href="/domains/">{% trans "Domains" %}</a></li> #}
{# <li><a href="/records/">{% trans "DNS records" %}</a></li> #}
{# <li><a href="/blacklist/">{% trans "Blacklist" %}</a></li> #}
......@@ -16,26 +16,27 @@
# with CIRCLE. If not, see <http://www.gnu.org/licenses/>.
from django.conf.urls import patterns, url
from .views import (IndexView,
from .views import (
IndexView,
HostList, HostDetail, HostCreate, HostDelete,
VlanList, VlanDetail, VlanDelete, VlanCreate,
DomainList, DomainDetail, DomainDelete, DomainCreate,
GroupList, GroupDetail, GroupDelete, GroupCreate,
RecordList, RecordDetail, RecordCreate, RecordDelete,
BlacklistList, BlacklistDetail, BlacklistDelete,
BlacklistCreate,
BlacklistList, BlacklistDetail, BlacklistDelete, BlacklistCreate,
RuleList, RuleDetail, RuleDelete, RuleCreate,
SwitchPortList, SwitchPortDetail, SwitchPortCreate,
SwitchPortDelete,
VlanGroupList, VlanGroupDetail, VlanGroupDelete,
VlanGroupCreate,
SwitchPortList, SwitchPortDetail, SwitchPortCreate, SwitchPortDelete,
VlanGroupList, VlanGroupDetail, VlanGroupDelete, VlanGroupCreate,
FirewallList, FirewallDetail, FirewallCreate, FirewallDelete,
remove_host_group, add_host_group,
remove_switch_port_device, add_switch_port_device,
VlanAclUpdateView)
VlanAclUpdateView
)
urlpatterns = patterns(
'',
url('^$', IndexView.as_view(), name='network.index'),
# blacklist
url('^blacklist/$', BlacklistList.as_view(),
name='network.blacklist_list'),
url('^blacklist/create$', BlacklistCreate.as_view(),
......@@ -44,6 +45,8 @@ urlpatterns = patterns(
name='network.blacklist'),
url('^blacklist/delete/(?P<pk>\d+)/$', BlacklistDelete.as_view(),
name="network.blacklist_delete"),
# domain
url('^domains/$', DomainList.as_view(), name='network.domain_list'),
url('^domains/create$', DomainCreate.as_view(),
name='network.domain_create'),
......@@ -51,17 +54,33 @@ urlpatterns = patterns(
name='network.domain'),
url('^domains/delete/(?P<pk>\d+)/$', DomainDelete.as_view(),
name="network.domain_delete"),
# firewall
url('^firewalls/$', FirewallList.as_view(),
name='network.firewall_list'),
url('^firewalls/create$', FirewallCreate.as_view(),
name='network.firewall_create'),
url('^firewalls/(?P<pk>\d+)/$', FirewallDetail.as_view(),
name='network.firewall'),
url('^firewalls/delete/(?P<pk>\d+)/$', FirewallDelete.as_view(),
name="network.firewall_delete"),
# group (host)
url('^groups/$', GroupList.as_view(), name='network.group_list'),
url('^groups/create$', GroupCreate.as_view(),
name='network.group_create'),
url('^groups/(?P<pk>\d+)/$', GroupDetail.as_view(), name='network.group'),
url('^groups/delete/(?P<pk>\d+)/$', GroupDelete.as_view(),
name="network.group_delete"),
# host
url('^hosts/$', HostList.as_view(), name='network.host_list'),
url('^hosts/create$', HostCreate.as_view(), name='network.host_create'),
url('^hosts/(?P<pk>\d+)/$', HostDetail.as_view(), name='network.host'),
url('^hosts/delete/(?P<pk>\d+)/$', HostDelete.as_view(),
name="network.host_delete"),
# record
url('^records/$', RecordList.as_view(), name='network.record_list'),
url('^records/create$', RecordCreate.as_view(),
name='network.record_create'),
......@@ -69,10 +88,14 @@ urlpatterns = patterns(
name='network.record'),
url('^records/delete/(?P<pk>\d+)/$', RecordDelete.as_view(),
name="network.record_delete"),
# rule
url('^rules/$', RuleList.as_view(), name='network.rule_list'),
url('^rules/create$', RuleCreate.as_view(), name='network.rule_create'),
url('^rules/(?P<pk>\d+)/$', RuleDetail.as_view(),
name='network.rule'),
# switchport
url('^switchports/$', SwitchPortList.as_view(),
name='network.switch_port_list'),
url('^switchports/create$', SwitchPortCreate.as_view(),
......@@ -81,6 +104,8 @@ urlpatterns = patterns(
name='network.switch_port'),
url('^switchports/delete/(?P<pk>\d+)/$', SwitchPortDelete.as_view(),
name="network.switch_port_delete"),
# vlan
url('^vlans/$', VlanList.as_view(), name='network.vlan_list'),
url('^vlans/create$', VlanCreate.as_view(), name='network.vlan_create'),
url('^vlans/(?P<vid>\d+)/$', VlanDetail.as_view(), name='network.vlan'),
......@@ -88,6 +113,8 @@ urlpatterns = patterns(
name='network.vlan-acl'),
url('^vlans/delete/(?P<vid>\d+)/$', VlanDelete.as_view(),
name="network.vlan_delete"),
# vlangroup
url('^vlangroups/$', VlanGroupList.as_view(),
name='network.vlan_group_list'),
url('^vlangroups/create$', VlanGroupCreate.as_view(),
......
......@@ -28,15 +28,20 @@ from django.db.models import Q
from django_tables2 import SingleTableView
from firewall.models import (Host, Vlan, Domain, Group, Record, BlacklistItem,
Rule, VlanGroup, SwitchPort, EthernetDevice)
from firewall.models import (
Host, Vlan, Domain, Group, Record, BlacklistItem, Rule, VlanGroup,
SwitchPort, EthernetDevice, Firewall)
from vm.models import Interface
from .tables import (HostTable, VlanTable, SmallHostTable, DomainTable,
GroupTable, RecordTable, BlacklistItemTable, RuleTable,
VlanGroupTable, SmallRuleTable, SmallGroupRuleTable,
SmallRecordTable, SwitchPortTable, SmallDhcpTable, )
from .forms import (HostForm, VlanForm, DomainForm, GroupForm, RecordForm,
BlacklistItemForm, RuleForm, VlanGroupForm, SwitchPortForm)
from .tables import (
HostTable, VlanTable, SmallHostTable, DomainTable, GroupTable,
RecordTable, BlacklistItemTable, RuleTable, VlanGroupTable,
SmallRuleTable, SmallGroupRuleTable, SmallRecordTable, SwitchPortTable,
SmallDhcpTable, FirewallTable, FirewallRuleTable,
)
from .forms import (
HostForm, VlanForm, DomainForm, GroupForm, RecordForm, BlacklistItemForm,
RuleForm, VlanGroupForm, SwitchPortForm, FirewallForm
)
from django.contrib import messages
from django.contrib.messages.views import SuccessMessageMixin
......@@ -287,6 +292,53 @@ class DomainDelete(LoginRequiredMixin, SuperuserRequiredMixin, DeleteView):
return context
class FirewallList(LoginRequiredMixin, SuperuserRequiredMixin,
SingleTableView):
model = Firewall
table_class = FirewallTable
template_name = "network/firewall-list.html"
table_pagination = False
class FirewallDetail(LoginRequiredMixin, SuperuserRequiredMixin,
SuccessMessageMixin, UpdateView):
model = Firewall
template_name = "network/firewall-edit.html"
form_class = FirewallForm
success_message = _(u'Succesfully modified firewall.')
def get_success_url(self):
if 'pk' in self.kwargs:
return reverse_lazy('network.firewall', kwargs=self.kwargs)
def get_context_data(self, **kwargs):
context = super(FirewallDetail, self).get_context_data(**kwargs)
rules = Rule.objects.filter(firewall=self.object)
context['rule_table'] = FirewallRuleTable(rules,
request=self.request)
return context
class FirewallCreate(LoginRequiredMixin, SuperuserRequiredMixin,
SuccessMessageMixin, CreateView):
model = Firewall
template_name = "network/firewall-create.html"
form_class = FirewallForm
success_message = _(u'Successfully created firewall.')
class FirewallDelete(LoginRequiredMixin, SuperuserRequiredMixin, DeleteView):
model = Firewall
template_name = "network/confirm/base_delete.html"
def get_success_url(self):
next = self.request.POST.get('next')
if next:
return next
else:
return reverse_lazy('network.firewall_list')
class GroupList(LoginRequiredMixin, SuperuserRequiredMixin, SingleTableView):
model = Group
table_class = GroupTable
......
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