Commit 7e4f4b67 by Kálmán Viktor

Merge branch 'master' into feature-request

parents 1d7264f7 6a7ca8f5
# -*- coding: utf-8 -*-
import datetime
from south.db import db
from south.v2 import SchemaMigration
from django.db import models
class Migration(SchemaMigration):
def forwards(self, orm):
# Adding model 'Level'
db.create_table(u'acl_level', (
(u'id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
('name', self.gf('django.db.models.fields.CharField')(max_length=50)),
('content_type', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['contenttypes.ContentType'])),
('codename', self.gf('django.db.models.fields.CharField')(max_length=100)),
('weight', self.gf('django.db.models.fields.IntegerField')(null=True)),
))
db.send_create_signal(u'acl', ['Level'])
# Adding unique constraint on 'Level', fields ['content_type', 'codename']
db.create_unique(u'acl_level', ['content_type_id', 'codename'])
# Adding model 'ObjectLevel'
db.create_table(u'acl_objectlevel', (
(u'id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
('level', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['acl.Level'])),
('content_type', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['contenttypes.ContentType'])),
('object_id', self.gf('django.db.models.fields.CharField')(max_length=255)),
))
db.send_create_signal(u'acl', ['ObjectLevel'])
# Adding unique constraint on 'ObjectLevel', fields ['content_type', 'object_id', 'level']
db.create_unique(u'acl_objectlevel', ['content_type_id', 'object_id', 'level_id'])
# Adding M2M table for field users on 'ObjectLevel'
m2m_table_name = db.shorten_name(u'acl_objectlevel_users')
db.create_table(m2m_table_name, (
('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)),
('objectlevel', models.ForeignKey(orm[u'acl.objectlevel'], null=False)),
('user', models.ForeignKey(orm[u'auth.user'], null=False))
))
db.create_unique(m2m_table_name, ['objectlevel_id', 'user_id'])
# Adding M2M table for field groups on 'ObjectLevel'
m2m_table_name = db.shorten_name(u'acl_objectlevel_groups')
db.create_table(m2m_table_name, (
('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)),
('objectlevel', models.ForeignKey(orm[u'acl.objectlevel'], null=False)),
('group', models.ForeignKey(orm[u'auth.group'], null=False))
))
db.create_unique(m2m_table_name, ['objectlevel_id', 'group_id'])
def backwards(self, orm):
# Removing unique constraint on 'ObjectLevel', fields ['content_type', 'object_id', 'level']
db.delete_unique(u'acl_objectlevel', ['content_type_id', 'object_id', 'level_id'])
# Removing unique constraint on 'Level', fields ['content_type', 'codename']
db.delete_unique(u'acl_level', ['content_type_id', 'codename'])
# Deleting model 'Level'
db.delete_table(u'acl_level')
# Deleting model 'ObjectLevel'
db.delete_table(u'acl_objectlevel')
# Removing M2M table for field users on 'ObjectLevel'
db.delete_table(db.shorten_name(u'acl_objectlevel_users'))
# Removing M2M table for field groups on 'ObjectLevel'
db.delete_table(db.shorten_name(u'acl_objectlevel_groups'))
models = {
u'acl.level': {
'Meta': {'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Level'},
'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['contenttypes.ContentType']"}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}),
'weight': ('django.db.models.fields.IntegerField', [], {'null': 'True'})
},
u'acl.objectlevel': {
'Meta': {'unique_together': "(('content_type', 'object_id', 'level'),)", 'object_name': 'ObjectLevel'},
'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['contenttypes.ContentType']"}),
'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Group']", 'symmetrical': 'False'}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'level': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['acl.Level']"}),
'object_id': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'users': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.User']", 'symmetrical': 'False'})
},
u'auth.group': {
'Meta': {'object_name': 'Group'},
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
},
u'auth.permission': {
'Meta': {'ordering': "(u'content_type__app_label', u'content_type__model', u'codename')", 'unique_together': "((u'content_type', u'codename'),)", 'object_name': 'Permission'},
'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['contenttypes.ContentType']"}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
},
u'auth.user': {
'Meta': {'object_name': 'User'},
'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
},
u'contenttypes.contenttype': {
'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
}
}
complete_apps = ['acl']
\ No newline at end of file
# -*- coding: utf-8 -*-
import datetime
from south.db import db
from south.v2 import SchemaMigration
from django.db import models
class Migration(SchemaMigration):
def forwards(self, orm):
# Changing field 'ObjectLevel.object_id'
# db.alter_column(u'acl_objectlevel', 'object_id', self.gf('django.db.models.fields.IntegerField')())
db.execute('''ALTER TABLE "acl_objectlevel"
ALTER COLUMN "object_id" SET NOT NULL,
ALTER COLUMN "object_id" DROP DEFAULT,
ALTER COLUMN "object_id" TYPE integer USING ("object_id"::integer);''')
def backwards(self, orm):
# Changing field 'ObjectLevel.object_id'
db.alter_column(u'acl_objectlevel', 'object_id', self.gf('django.db.models.fields.CharField')(max_length=255))
models = {
u'acl.level': {
'Meta': {'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Level'},
'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['contenttypes.ContentType']"}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}),
'weight': ('django.db.models.fields.IntegerField', [], {'null': 'True'})
},
u'acl.objectlevel': {
'Meta': {'unique_together': "(('content_type', 'object_id', 'level'),)", 'object_name': 'ObjectLevel'},
'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['contenttypes.ContentType']"}),
'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Group']", 'symmetrical': 'False'}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'level': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['acl.Level']"}),
'object_id': ('django.db.models.fields.IntegerField', [], {}),
'users': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.User']", 'symmetrical': 'False'})
},
u'auth.group': {
'Meta': {'object_name': 'Group'},
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
},
u'auth.permission': {
'Meta': {'ordering': "(u'content_type__app_label', u'content_type__model', u'codename')", 'unique_together': "((u'content_type', u'codename'),)", 'object_name': 'Permission'},
'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['contenttypes.ContentType']"}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
},
u'auth.user': {
'Meta': {'object_name': 'User'},
'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
},
u'contenttypes.contenttype': {
'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
}
}
complete_apps = ['acl']
# register a signal do update permissions every migration.
# This is based on app django_extensions update_permissions command
from south.signals import post_migrate
from django.db.models.signals import post_migrate
def update_permissions_after_migration(app, **kwargs):
def update_permissions_after_migration(sender, **kwargs):
"""
Update app permission just after every migration.
This is based on app django_extensions update_permissions
......@@ -12,9 +12,9 @@ def update_permissions_after_migration(app, **kwargs):
"""
from django.conf import settings
from django.db.models import get_app, get_models
from django.db.models import get_models
from django.contrib.auth.management import create_permissions
create_permissions(get_app(app), get_models(), 2 if settings.DEBUG else 0)
create_permissions(sender, get_models(), 2 if settings.DEBUG else 0)
post_migrate.connect(update_permissions_after_migration)
......@@ -78,6 +78,9 @@ TEMPLATE_DEBUG = DEBUG
########## MANAGER CONFIGURATION
# See: https://docs.djangoproject.com/en/dev/ref/settings/#admins
ADMINS = (
('Root', 'root@localhost'),
)
EMAIL_SUBJECT_PREFIX = get_env_variable('DJANGO_SUBJECT_PREFIX', '[CIRCLE] ')
......@@ -339,10 +342,6 @@ THIRD_PARTY_APPS = (
'pipeline',
)
import django
if django.get_version() < '1.7':
THIRD_PARTY_APPS += 'south',
# Apps specific for this project go here.
LOCAL_APPS = (
......@@ -527,15 +526,6 @@ except:
LOCALE_PATHS = (join(SITE_ROOT, 'locale'), )
COMPANY_NAME = "BME IK 2014"
SOUTH_MIGRATION_MODULES = {
'taggit': 'taggit.south_migrations',
'vm': 'vm.south_migrations',
'firewall': 'firewall.south_migrations',
'acl': 'acl.south_migrations',
'dashboard': 'dashboard.south_migrations',
'storage': 'storage.south_migrations',
}
graphite_host = environ.get("GRAPHITE_HOST", None)
graphite_port = environ.get("GRAPHITE_PORT", None)
......@@ -562,3 +552,6 @@ MAX_NODE_RAM = get_env_variable("MAX_NODE_RAM", 1024)
CLIENT_DOWNLOAD_URL = get_env_variable('CLIENT_DOWNLOAD_URL', 'http://circlecloud.org/client/download/')
ADMIN_ENABLED = False
BLACKLIST_PASSWORD = get_env_variable("BLACKLIST_PASSWORD", "")
BLACKLIST_HOOK_URL = get_env_variable("BLACKLIST_HOOK_URL", "")
......@@ -27,21 +27,16 @@ from django.shortcuts import redirect
from circle.settings.base import get_env_variable
from dashboard.views import circle_login, HelpView
from dashboard.forms import CirclePasswordResetForm, CircleSetPasswordForm
from firewall.views import add_blacklist_item
admin.autodiscover()
urlpatterns = patterns(
'',
# url(r'^$', TemplateView.as_view(template_name='base.html')),
# Examples:
# url(r'^$', 'circle.views.home', name='home'),
# url(r'^circle/', include('circle.foo.urls')),
# url(r'^admin/doc/', include('django.contrib.admindocs.urls')),
url(r'^$', lambda x: redirect(reverse("dashboard.index"))),
url(r'^network/', include('network.urls')),
url(r'^blacklist-add/', add_blacklist_item),
url(r'^dashboard/', include('dashboard.urls')),
url(r'^request/', include('request.urls')),
......
......@@ -417,20 +417,6 @@ class HumanSortField(CharField):
setattr(model_instance, self.attname, value[:self.max_length])
return super(HumanSortField, self).pre_save(model_instance, add)
# allow South to handle these fields smoothly
try:
from south.modelsinspector import add_introspection_rules
add_introspection_rules(rules=[
(
(HumanSortField,),
[],
{'monitor': ('monitor', {}),
'maximum_number_length': ('maximum_number_length', {}), }
),
], patterns=['common\.models\.'])
except ImportError:
pass
class HumanReadableObject(object):
def __init__(self, user_text_template, admin_text_template, params):
......
......@@ -1251,12 +1251,21 @@ textarea[name="new_members"] {
#empty-vm-help {
position: absolute;
bottom: 70px;
right: 45px;
z-index: 99999;
right: 30px;
color: #101010;
text-align: right;
i {
padding-right: 10px;
}
}
#vm-detail-successfull-boot {
margin-bottom: 20px;
display: none;
}
#vm-detail-access-help {
background: #f9f9f9;
margin-top: 20px;
}
......@@ -50,7 +50,7 @@
{% trans "You have no virtual machines." %}
</div>
<div id="empty-vm-help">
{% trans "Use the <strong>new</strong> button to start a new VM" %}
{% trans "Use the <strong>new</strong> button to start a new VM" %}<br />
<i class="fa fa-arrow-down"></i>
</div>
{% endfor %}
......
......@@ -109,6 +109,39 @@
</div>
</div>
<div class="panel panel-default">
<div class="panel-heading">
<h4 class="no-margin">
<i class="fa fa-question-circle"></i>
{% trans "Access level rights" %}
</h4>
</div>
<div class="panel-body">
<dl>
<dt>{% trans "User" %}</dt>
<dd>
{% blocktrans %}
User can deploy instances from this template.
{% endblocktrans %}
</dd>
<dt>{% trans "Operator" %}</dt>
<dd>
{% blocktrans %}
Operators are able to deploy and grant/revoke User level access to this template.
{% endblocktrans %}
</dd>
<dt>{% trans "Owner" %}</dt>
<dd>
{% blocktrans %}
Owners can edit attributes or delete the template.
Owners are able to grant/revoke User, Operator and Owner level access to the template.
The accountable owner (the one who created the template) can not be demoted.
The accountable ownership can be transferred to other User via the "Transfer onwership" button.
{% endblocktrans %}
</dd>
</dl>
</div>
</div>
<div class="panel panel-default">
<div class="panel-heading">
......@@ -122,7 +155,7 @@
{% for d in disks %}
<li>
<i class="fa fa-file"></i>
{{ d.name }} (#{{ d.id }}) -
{{ d.name }} (#{{ d.id }})
<a href="{% url "dashboard.views.disk-remove" pk=d.pk %}?next={{ request.path }}"
data-disk-pk="{{ d.pk }}" class="btn btn-xs btn-danger pull-right disk-remove"
{% if not long_remove %}title="{% trans "Remove" %}"{% endif %}>
......
......@@ -18,3 +18,28 @@
</p>
<h3>{% trans "Permissions"|capfirst %}</h3>
{% include "dashboard/_manage_access.html" with table_id="vm-access-table" %}
<dl class="well well-sm" id="vm-detail-access-help">
<dt>{% trans "Permissions" %}</dt>
<dd>
{% trans "With Permissions you can add Users and Groups with different levels to grant access to the virtual machine." %}
</dd>
<dt>{% trans "User" %}</dt>
<dd>
{% trans "User level grants access to the virtual machine's details page. Users are able to connect to this machine." %}
</dd>
<dt>{% trans "Operator" %}</dt>
<dd>
{% blocktrans %}
Operator level permit the modification of the name and description fields. Allow the operator to open ports and grant/revoke User level access to the virtual machine.
{% endblocktrans %}
</dd>
<dt>{% trans "Owner" %}</dt>
<dd>
{% blocktrans %}
Owner level enables all operations on the virtual machine. Owners are able to grant/revoke Operator, User and Owner level access to others.
The accountable owner (the one who deployed the machine) can not be demoted. The accountable ownership can be transferred
to other User via the "Transfer onwership" button.
{% endblocktrans %}
</dd>
</dl>
......@@ -132,7 +132,8 @@ class RecordAdmin(admin.ModelAdmin):
class BlacklistItemAdmin(admin.ModelAdmin):
list_display = ('ipv4', 'type', 'reason', 'created_at', 'modified_at')
list_display = ('ipv4', 'whitelisted', 'reason', 'expires_at',
'created_at', 'modified_at')
class SwitchPortAdmin(admin.ModelAdmin):
......
......@@ -20,7 +20,6 @@ from django.core.exceptions import ValidationError
from django.db import models
from django.utils.translation import ugettext_lazy as _
from django.utils.ipv6 import is_valid_ipv6_address
from south.modelsinspector import add_introspection_rules
from django import forms
from netaddr import (IPAddress, IPNetwork, AddrFormatError, ZEROFILL,
EUI, mac_unix, AddrConversionError)
......@@ -203,9 +202,6 @@ class IPNetworkField(models.Field):
return super(IPNetworkField, self).formfield(**defaults)
add_introspection_rules([], ["firewall\.fields\."])
def val_alfanum(value):
"""Validate whether the parameter is a valid alphanumeric value."""
if not alfanum_re.match(value):
......
......@@ -19,14 +19,12 @@ import re
import logging
from collections import OrderedDict
from netaddr import IPAddress, AddrFormatError
from datetime import timedelta
from itertools import product
from .models import (Host, Rule, Vlan, Domain, Record, BlacklistItem,
SwitchPort)
from .iptables import IptRule, IptChain
import django.conf
from django.db.models import Q
from django.template import loader, Context
from django.utils import timezone
......@@ -161,10 +159,9 @@ class BuildFirewall:
def ipset():
week = timezone.now() - timedelta(days=2)
filter_ban = (Q(type='tempban', modified_at__gte=week) |
Q(type='permban'))
return BlacklistItem.objects.filter(filter_ban).values('ipv4', 'reason')
now = timezone.now()
return BlacklistItem.objects.filter(whitelisted=False).exclude(
expires_at__lt=now).values('ipv4', 'reason')
def ipv6_to_octal(ipv6):
......
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import models, migrations
class Migration(migrations.Migration):
dependencies = [
('firewall', '0002_auto_20150115_0021'),
]
operations = [
migrations.RemoveField(
model_name='blacklistitem',
name='type',
),
migrations.AddField(
model_name='blacklistitem',
name='expires_at',
field=models.DateTimeField(default=None, null=True, verbose_name='expires at', blank=True),
preserve_default=True,
),
migrations.AddField(
model_name='blacklistitem',
name='whitelisted',
field=models.BooleanField(default=False, verbose_name='whitelisted'),
preserve_default=True,
),
migrations.AlterField(
model_name='blacklistitem',
name='ipv4',
field=models.GenericIPAddressField(protocol=b'ipv4', unique=True, verbose_name=b'IPv4 address'),
preserve_default=True,
),
migrations.AlterField(
model_name='blacklistitem',
name='reason',
field=models.TextField(null=True, verbose_name='reason', blank=True),
preserve_default=True,
),
migrations.AlterField(
model_name='blacklistitem',
name='snort_message',
field=models.TextField(null=True, verbose_name='short message', blank=True),
preserve_default=True,
),
]
......@@ -1109,24 +1109,23 @@ class EthernetDevice(models.Model):
class BlacklistItem(models.Model):
CHOICES_type = (('permban', 'permanent ban'), ('tempban', 'temporary ban'),
('whitelist', 'whitelist'), ('tempwhite', 'tempwhite'))
ipv4 = models.GenericIPAddressField(protocol='ipv4', unique=True)
host = models.ForeignKey('Host', blank=True, null=True,
verbose_name=_('host'))
reason = models.TextField(blank=True, verbose_name=_('reason'))
snort_message = models.TextField(blank=True,
verbose_name=_('short message'))
type = models.CharField(
max_length=10,
choices=CHOICES_type,
default='tempban',
verbose_name=_('type')
)
ipv4 = models.GenericIPAddressField(
protocol='ipv4', unique=True, verbose_name=("IPv4 address"))
host = models.ForeignKey(
'Host', blank=True, null=True, verbose_name=_('host'))
reason = models.TextField(
blank=True, null=True, verbose_name=_('reason'))
snort_message = models.TextField(
blank=True, null=True, verbose_name=_('short message'))
whitelisted = models.BooleanField(
default=False, verbose_name=_("whitelisted"))
created_at = models.DateTimeField(auto_now_add=True,
verbose_name=_('created_at'))
modified_at = models.DateTimeField(auto_now=True,
verbose_name=_('modified_at'))
expires_at = models.DateTimeField(blank=True, null=True, default=None,
verbose_name=_('expires at'))
def save(self, *args, **kwargs):
self.full_clean()
......
# -*- coding: utf-8 -*-
import datetime
from south.db import db
from south.v2 import SchemaMigration
from django.db import models
class Migration(SchemaMigration):
def forwards(self, orm):
# Adding field 'Rule.owner'
db.add_column('firewall_rule', 'owner',
self.gf('django.db.models.fields.related.ForeignKey')(default=1, to=orm['auth.User']),
keep_default=False)
# Changing field 'Host.mac'
db.alter_column('firewall_host', 'mac', self.gf('firewall.fields.MACAddressField')(unique=True, max_length=17))
def backwards(self, orm):
# Deleting field 'Rule.owner'
db.delete_column('firewall_rule', 'owner_id')
# Changing field 'Host.mac'
db.alter_column('firewall_host', 'mac', self.gf('firewall.models.MACAddressField')(max_length=17, unique=True))
models = {
'auth.group': {
'Meta': {'object_name': 'Group'},
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
},
'auth.permission': {
'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'},
'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
},
'auth.user': {
'Meta': {'object_name': 'User'},
'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
'first_name': ('django.db.models.fields.CharField', [], {