From 9060ddd77b87764667cdc23620a0de256cccb54e Mon Sep 17 00:00:00 2001
From: django <cloud@devenv.(none)>
Date: Fri, 25 Jan 2013 14:50:59 +0100
Subject: [PATCH] firewall: django modeldict

---
 firewall/admin.py                             |  19 ++++++++++++++-----
 firewall/fw.py                                |  76 ++++++++++++++++++++++++++++++++++++++++++++++++----------------------------
 firewall/migrations/0020_auto__add_setting.py | 142 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 firewall/models.py                            |   7 +++++++
 firewall/tasks.py                             |   8 ++++++--
 5 files changed, 217 insertions(+), 35 deletions(-)
 create mode 100644 firewall/migrations/0020_auto__add_setting.py

diff --git a/firewall/admin.py b/firewall/admin.py
index d1abc9f..e36ad7f 100644
--- a/firewall/admin.py
+++ b/firewall/admin.py
@@ -1,24 +1,34 @@
 from django.contrib import admin
 from firewall.models import *
+from django import contrib
 
 
+class AliasInline(contrib.admin.TabularInline):
+    model = Alias
+
 class HostAdmin(admin.ModelAdmin):
     list_display = ('hostname', 'vlan', 'ipv4', 'ipv6', 'pub_ipv4', 'mac', 'shared_ip', 'owner', 'groups_l', 'rules_l', 'description', 'reverse')
-    ordering = ('hostname',)
+    ordering = ('hostname', )
     list_filter = ('owner', 'vlan', 'groups')
     search_fields = ('hostname', 'description', 'ipv4', 'ipv6', 'mac')
-    filter_horizontal = ('groups', 'rules',)
+    filter_horizontal = ('groups', 'rules', )
+    inlines = (AliasInline, )
+
+class HostInline(contrib.admin.TabularInline):
+    model = Host
+    fields = ('hostname', 'ipv4', 'ipv6', 'pub_ipv4', 'mac', 'shared_ip', 'owner', 'reverse')
 
 class VlanAdmin(admin.ModelAdmin):
     list_display = ('vid', 'name', 'rules_l', 'ipv4', 'net_ipv4', 'ipv6', 'net_ipv6', 'description', 'domain', 'snat_ip', 'snat_to_l')
-    ordering = ('vid',)
+    ordering = ('vid', )
+    inlines = (HostInline, )
 
 class RuleAdmin(admin.ModelAdmin):
     list_display = ('r_type', 'color_desc', 'description', 'vlan_l', 'owner', 'extra', 'direction', 'accept', 'proto', 'sport', 'dport', 'nat', 'nat_dport')
     list_filter = ('r_type', 'vlan', 'owner', 'direction', 'accept', 'proto', 'nat')
 
 class AliasAdmin(admin.ModelAdmin):
-        list_display = ('alias', 'host')
+    list_display = ('alias', 'host')
 
 
 admin.site.register(Host, HostAdmin)
@@ -27,4 +37,3 @@ admin.site.register(Rule, RuleAdmin)
 admin.site.register(Alias, AliasAdmin)
 admin.site.register(Group)
 admin.site.register(Firewall)
-
diff --git a/firewall/fw.py b/firewall/fw.py
index cbb2834..9581e3f 100644
--- a/firewall/fw.py
+++ b/firewall/fw.py
@@ -1,10 +1,11 @@
 from django.contrib import auth
 from firewall import models
+from modeldict import *
 import os
 
 import subprocess
 import re
-DNS_SERVER = "152.66.243.60"
+import json
 
 
 class firewall:
@@ -291,6 +292,12 @@ def ipv6_to_octal(ipv6):
             octets.append(int(part[2:], 16))
     return '\\' + '\\'.join(['%03o' % x for x in octets])
 
+def ipv4_to_arpa(ipv4, cname=False):
+    m2 = re.search(r'^([0-9]+)\.([0-9]+)\.([0-9]+)\.([0-9]+)$', ipv4)
+    if(cname):
+        return "%s.dns1.%s.%s.%s.in-addr.arpa" % (m2.group(4), m2.group(3), m2.group(2), m2.group(1))
+    else:
+        return "%s.%s.%s.%s.in-addr.arpa" % (m2.group(4), m2.group(3), m2.group(2), m2.group(1))
 
 def ipv6_to_arpa(ipv6):
     while len(ipv6.split(':')) < 8:
@@ -310,52 +317,65 @@ def ipv6_to_arpa(ipv6):
 
 
 
+# =fqdn:ip:ttl          A, PTR
+# &fqdn:ip:x:ttl        NS
+# ZfqdnSOA
+# +fqdn:ip:ttl          A
+# ^                     PTR
+# C                     CNAME
+# :                     generic
+
 def dns():
     vlans = models.Vlan.objects.all()
     regex = re.compile(r'^([0-9]+)\.([0-9]+)\.([0-9]+)\.([0-9]+)$')
     DNS = []
-    DNS.append("=cloud.ik.bme.hu:152.66.243.98:600::\n")
-    DNS.append(":cloud.ik.bme.hu:28:\040\001\007\070\040\001\100\061\000\002\000\000\000\007\000\000:600\n")
-# tarokkknak
-    DNS.append("^%s.dns1.%s.%s.%s.in-addr.arpa:%s:600::\n" % (75, 243, 66, 152, "se.hpc.iit.bme.hu"))
-    DNS.append("^%s.dns1.%s.%s.%s.in-addr.arpa:%s:600::\n" % (76, 243, 66, 152, "ce.hpc.iit.bme.hu"))
-    DNS.append("^%s.dns1.%s.%s.%s.in-addr.arpa:%s:600::\n" % (77, 243, 66, 152, "mon.hpc.iit.bme.hu"))
-    DNS.append("^%s.dns1.%s.%s.%s.in-addr.arpa:%s:600::\n" % (62, 243, 66, 152, "r.cloud.ik.bme.hu"))
-    DNS.append("=r.cloud.ik.bme.hu:152.66.243.62:600::\n")
+    DNS.append("=cloud.ik.bme.hu:152.66.243.98:600::")
+    DNS.append(":cloud.ik.bme.hu:28:\040\001\007\070\040\001\100\061\000\002\000\000\000\007\000\000:600")
+    DNS.append("=r.cloud.ik.bme.hu:152.66.243.62:600::")
 
 
-    DNS.append("Z1.3.0.4.1.0.0.2.8.3.7.0.1.0.0.2.ip6.arpa:dns1.ik.bme.hu:support.ik.bme.hu::::::600\n") # soa
-    DNS.append("&1.3.0.4.1.0.0.2.8.3.7.0.1.0.0.2.ip6.arpa::dns1.ik.bme.hu:600::\n")      # ns rekord
-    DNS.append("&1.3.0.4.1.0.0.2.8.3.7.0.1.0.0.2.ip6.arpa::nic.bme.hu:600::\n")      # ns rekord
-#   DNS.append("&1.3.0.4.1.0.0.2.8.3.7.0.1.0.0.2.ip6.arpa::ns.bme.hu:600::\n")      # ns rekord
+    DNS.append("Z1.3.0.4.1.0.0.2.8.3.7.0.1.0.0.2.ip6.arpa:dns1.ik.bme.hu:support.ik.bme.hu::::::600") # soa
+    DNS.append("&1.3.0.4.1.0.0.2.8.3.7.0.1.0.0.2.ip6.arpa::dns1.ik.bme.hu:600::")      # ns rekord
+    DNS.append("&1.3.0.4.1.0.0.2.8.3.7.0.1.0.0.2.ip6.arpa::nic.bme.hu:600::")      # ns rekord
 
     for i_vlan in vlans:
         m = regex.search(i_vlan.net4)
         if(i_vlan.name != "DMZ" and i_vlan.name != "PUB"):
-            DNS.append("Z%s.%s.in-addr.arpa:dns1.ik.bme.hu:support.ik.bme.hu::::::600\n" % (m.group(2), m.group(1)))
-            DNS.append("&%s.%s.in-addr.arpa::dns1.ik.bme.hu:600::\n" % (m.group(2), m.group(1)))
-            DNS.append("Z%s:dns1.ik.bme.hu:support.ik.bme.hu::::::600\n" % i_vlan.domain)
-            DNS.append("&%s::dns1.ik.bme.hu:600::\n" % i_vlan.domain)
+            DNS.append("Z%s.%s.in-addr.arpa:%s:support.ik.bme.hu::::::%s" % (m.group(2), m.group(1), models.settings['dns_hostname'], models.settings['dns_ttl']))
+            DNS.append("&%s.%s.in-addr.arpa::%s:%s:" % (m.group(2), m.group(1), models.settings['dns_hostname'], models.settings['dns_ttl']))
+            DNS.append("Z%s:%s:support.ik.bme.hu::::::%s" % (i_vlan.domain, models.settings['dns_hostname'], models.settings['dns_ttl']))
+            DNS.append("&%s::%s:%s" % (i_vlan.domain, models.settings['dns_hostname'], models.settings['dns_ttl']))
             if(i_vlan.name == "WAR"):
-                DNS.append("Zdns1.%s.%s.%s.in-addr.arpa:dns1.ik.bme.hu:support.ik.bme.hu::::::600\n" % (m.group(3), m.group(2), m.group(1)))
-                DNS.append("&dns1.%s.%s.%s.in-addr.arpa::dns1.ik.bme.hu:600::\n" % (m.group(3), m.group(2), m.group(1)))
+                DNS.append("Zdns1.%s.%s.%s.in-addr.arpa:%s:support.ik.bme.hu::::::%s" % (m.group(3), m.group(2), m.group(1), models.settings['dns_hostname'], models.settings['dns_ttl']))
+                DNS.append("&dns1.%s.%s.%s.in-addr.arpa::%s:%s::" % (m.group(3), m.group(2), m.group(1), models.settings['dns_hostname'], models.settings['dns_ttl']))
         for i_host in i_vlan.host_set.all():
             ipv4 = ( i_host.pub_ipv4 if i_host.pub_ipv4 and not i_host.shared_ip else i_host.ipv4 )
-            m2 = regex.search(ipv4)
+            reverse = i_host.reverse if(i_host.reverse and len(i_host.reverse)) else i_host.hostname + u'.' + i_vlan.domain
+            hostname = i_host.hostname + u'.' + i_vlan.domain
+
             # ipv4
-            DNS.append("+%s:%s:600::\n" % (i_host.hostname + u'.' + i_vlan.domain, ipv4))
-            DNS.append("^%s.%s.%s.%s.in-addr.arpa:%s:600::\n" % (m2.group(4), m2.group(3), m2.group(2), m2.group(1), i_host.reverse if(i_host.reverse and len(i_host.reverse)) else i_host.hostname + u'.' + i_vlan.domain))
-            DNS.append("^%s.dns1.%s.%s.%s.in-addr.arpa:%s:600::\n" % (m2.group(4), m2.group(3), m2.group(2), m2.group(1), i_host.reverse if(i_host.reverse and len(i_host.reverse)) else i_host.hostname + u'.' + i_vlan.domain))
+            if i_host.ipv4:
+                # A record
+                DNS.append("+%s:%s:%s" % (hostname, ipv4, models.settings['dns_ttl']))
+                # PTR record 4.3.2.1.in-addr.arpa
+                DNS.append("^%s:%s:%s" % (ipv4_to_arpa(i_host.ipv4), reverse, models.settings['dns_ttl']))
+                # PTR record 4.dns1.3.2.1.in-addr.arpa
+                DNS.append("^%s:%s:%s" % (ipv4_to_arpa(i_host.ipv4, cname=True), reverse, models.settings['dns_ttl']))
+
             # ipv6
             if i_host.ipv6:
-                DNS.append(":%s:28:%s:600\n" % (i_host.hostname + u'.' + i_vlan.domain, ipv6_to_octal(i_host.ipv6)))
-                DNS.append("^%s:%s:600::\n" % (ipv6_to_arpa(i_host.ipv6), i_host.reverse if(i_host.reverse and len(i_host.reverse)) else i_host.hostname + u'.' + i_vlan.domain))
+                # AAAA record
+                DNS.append(":%s:28:%s:%s" % (hostname, ipv6_to_octal(i_host.ipv6), models.settings['dns_ttl']))
+                # PTR record
+                DNS.append("^%s:%s:%s" % (ipv6_to_arpa(i_host.ipv6), reverse, models.settings['dns_ttl']))
+
             # cname
             for i_alias in i_host.alias_set.all():
-                DNS.append("C%s:%s.%s:600\n" % (i_alias.alias, i_host.hostname, i_vlan.domain))
+                DNS.append("C%s:%s:%s" % (i_alias.alias, hostname, models.settings['dns_ttl']))
 
-    process = subprocess.Popen(['/usr/bin/ssh', 'tinydns@%s' % DNS_SERVER], shell=False, stdin=subprocess.PIPE)
+    process = subprocess.Popen(['/usr/bin/ssh', 'tinydns@%s' % models.settings['dns_hostname']], shell=False, stdin=subprocess.PIPE)
     process.communicate("\n".join(DNS)+"\n")
+    # print "\n".join(DNS)+"\n"
 
 
 def prefix_to_mask(prefix):
@@ -396,7 +416,7 @@ def dhcp():
                     'domain': i_vlan.domain,
                     'router': i_vlan.ipv4,
                     'ntp': i_vlan.ipv4,
-                    'dnsserver': DNS_SERVER,
+                    'dnsserver': models.settings['rdns_ip'],
                     'extra': "range %s" % i_vlan.dhcp_pool if m else "deny unknown-clients",
                     'interface': i_vlan.interface,
                     'name': i_vlan.name,
diff --git a/firewall/migrations/0020_auto__add_setting.py b/firewall/migrations/0020_auto__add_setting.py
new file mode 100644
index 0000000..93cf3f2
--- /dev/null
+++ b/firewall/migrations/0020_auto__add_setting.py
@@ -0,0 +1,142 @@
+# -*- 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 'Setting'
+        db.create_table('firewall_setting', (
+            ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
+            ('key', self.gf('django.db.models.fields.CharField')(max_length=32)),
+            ('value', self.gf('django.db.models.fields.CharField')(max_length=200)),
+        ))
+        db.send_create_signal('firewall', ['Setting'])
+
+
+    def backwards(self, orm):
+        # Deleting model 'Setting'
+        db.delete_table('firewall_setting')
+
+
+    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', [], {'max_length': '30', 'blank': 'True'}),
+            'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
+            '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': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
+            'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
+        },
+        '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'}),
+            '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'})
+        },
+        'firewall.alias': {
+            'Meta': {'object_name': 'Alias'},
+            'alias': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '40'}),
+            'host': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['firewall.Host']"}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'})
+        },
+        'firewall.firewall': {
+            'Meta': {'object_name': 'Firewall'},
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '20'}),
+            'rules': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': "orm['firewall.Rule']", 'null': 'True', 'blank': 'True'})
+        },
+        'firewall.group': {
+            'Meta': {'object_name': 'Group'},
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '20'}),
+            'rules': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': "orm['firewall.Rule']", 'null': 'True', 'blank': 'True'})
+        },
+        'firewall.host': {
+            'Meta': {'object_name': 'Host'},
+            'comment': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
+            'description': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
+            'groups': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': "orm['firewall.Group']", 'null': 'True', 'blank': 'True'}),
+            'hostname': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '40'}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'ipv4': ('django.db.models.fields.GenericIPAddressField', [], {'unique': 'True', 'max_length': '39'}),
+            'ipv6': ('django.db.models.fields.GenericIPAddressField', [], {'max_length': '39', 'unique': 'True', 'null': 'True', 'blank': 'True'}),
+            'location': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
+            'mac': ('firewall.fields.MACAddressField', [], {'unique': 'True', 'max_length': '17'}),
+            'owner': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"}),
+            'pub_ipv4': ('django.db.models.fields.GenericIPAddressField', [], {'max_length': '39', 'null': 'True', 'blank': 'True'}),
+            'reverse': ('django.db.models.fields.CharField', [], {'max_length': '40', 'null': 'True', 'blank': 'True'}),
+            'rules': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': "orm['firewall.Rule']", 'null': 'True', 'blank': 'True'}),
+            'shared_ip': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+            'vlan': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['firewall.Vlan']"})
+        },
+        'firewall.rule': {
+            'Meta': {'object_name': 'Rule'},
+            'accept': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+            'description': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
+            'direction': ('django.db.models.fields.CharField', [], {'max_length': '1'}),
+            'dport': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
+            'extra': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'nat': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+            'nat_dport': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
+            'owner': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True', 'blank': 'True'}),
+            'proto': ('django.db.models.fields.CharField', [], {'max_length': '10', 'null': 'True', 'blank': 'True'}),
+            'r_type': ('django.db.models.fields.CharField', [], {'max_length': '10'}),
+            'sport': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
+            'vlan': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': "orm['firewall.Vlan']", 'null': 'True', 'blank': 'True'})
+        },
+        'firewall.setting': {
+            'Meta': {'object_name': 'Setting'},
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'key': ('django.db.models.fields.CharField', [], {'max_length': '32'}),
+            'value': ('django.db.models.fields.CharField', [], {'max_length': '200'})
+        },
+        'firewall.vlan': {
+            'Meta': {'object_name': 'Vlan'},
+            'comment': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
+            'description': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
+            'dhcp_pool': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
+            'domain': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'interface': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '20'}),
+            'ipv4': ('django.db.models.fields.GenericIPAddressField', [], {'unique': 'True', 'max_length': '39'}),
+            'ipv6': ('django.db.models.fields.GenericIPAddressField', [], {'unique': 'True', 'max_length': '39'}),
+            'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '20'}),
+            'net4': ('django.db.models.fields.GenericIPAddressField', [], {'unique': 'True', 'max_length': '39'}),
+            'net6': ('django.db.models.fields.GenericIPAddressField', [], {'unique': 'True', 'max_length': '39'}),
+            'prefix4': ('django.db.models.fields.IntegerField', [], {'default': '16'}),
+            'prefix6': ('django.db.models.fields.IntegerField', [], {'default': '80'}),
+            'rules': ('django.db.models.fields.related.ManyToManyField', [], {'blank': 'True', 'related_name': "'firewall_vlan_related'", 'null': 'True', 'symmetrical': 'False', 'to': "orm['firewall.Rule']"}),
+            'snat_ip': ('django.db.models.fields.GenericIPAddressField', [], {'max_length': '39', 'null': 'True', 'blank': 'True'}),
+            'snat_to': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': "orm['firewall.Vlan']", 'null': 'True', 'blank': 'True'}),
+            'vid': ('django.db.models.fields.IntegerField', [], {'unique': 'True'})
+        }
+    }
+
+    complete_apps = ['firewall']
\ No newline at end of file
diff --git a/firewall/models.py b/firewall/models.py
index ee6df3d..2a2fef1 100644
--- a/firewall/models.py
+++ b/firewall/models.py
@@ -7,6 +7,13 @@ from django.utils.translation import ugettext_lazy as _
 from firewall.fields import *
 from south.modelsinspector import add_introspection_rules
 from django.core.validators import MinValueValidator, MaxValueValidator
+from modeldict import ModelDict
+
+class Setting(models.Model):
+    key = models.CharField(max_length=32)
+    value = models.CharField(max_length=200)
+
+settings = ModelDict(Setting, key='key', value='value', instances=False)
 
 class Rule(models.Model):
     CHOICES_type = (('host', 'host'), ('firewall', 'firewall'), ('vlan', 'vlan'))
diff --git a/firewall/tasks.py b/firewall/tasks.py
index 26c7e63..b9fc008 100644
--- a/firewall/tasks.py
+++ b/firewall/tasks.py
@@ -3,7 +3,7 @@ from django.core.cache import cache
 import os
 import time
 from firewall.fw import *
-
+from firewall.models import settings
 
 def reload_firewall_lock():
     acquire_lock = lambda: cache.add("reload_lock1", "true", 9)
@@ -25,7 +25,11 @@ class ReloadTask(Task):
             return
 
         print "indul"
-        time.sleep(10)
+        try:
+            sleep = float(settings['reload_sleep'])
+        except:
+            sleep = 10
+        time.sleep(sleep)
 
         try:
             print "ipv4"
--
libgit2 0.26.0