Added all objects during form cleaning for same rules
[flowspy] / flowspec / models.py
index 2574ea5..3f9e57f 100644 (file)
@@ -8,12 +8,12 @@ from utils import proxy as PR
 from ipaddr import *
 import datetime
 import logging
-from flowspec.tasks import *
 from time import sleep
 
-from flowspy.utils import beanstalkc
+import beanstalkc
 from flowspy.utils.randomizer import id_generator as id_gen
 
+from flowspec.tasks import *
 
 FORMAT = '%(asctime)s %(levelname)s: %(message)s'
 logging.basicConfig(format=FORMAT)
@@ -39,6 +39,23 @@ THEN_CHOICES = (
     ("sample", "Sample")                
 )
 
+MATCH_PROTOCOL = (
+    ("ah", "ah"),
+    ("egp", "egp"),
+    ("esp", "esp"),
+    ("gre", "gre"),
+    ("icmp", "icmp"),
+    ("icmp6", "icmp6"),
+    ("igmp", "igmp"),
+    ("ipip", "ipip"),
+    ("ospf", "ospf"),
+    ("pim", "pim"),
+    ("rsvp", "rsvp"),
+    ("sctp", "sctp"),
+    ("tcp", "tcp"),
+    ("udp", "udp"),
+)
+
 ROUTE_STATES = (
     ("ACTIVE", "ACTIVE"),
     ("ERROR", "ERROR"),
@@ -66,6 +83,13 @@ class MatchDscp(models.Model):
     class Meta:
         db_table = u'match_dscp'
 
+class MatchProtocol(models.Model):
+    protocol = models.CharField(max_length=24, unique=True)
+    def __unicode__(self):
+        return self.protocol
+    class Meta:
+        db_table = u'match_protocol'
+
    
 class ThenAction(models.Model):
     action = models.CharField(max_length=60, choices=THEN_CHOICES, verbose_name="Action")
@@ -81,7 +105,7 @@ class ThenAction(models.Model):
 class Route(models.Model):
     name = models.SlugField(max_length=128)
     applier = models.ForeignKey(User, blank=True, null=True)
-    source = models.CharField(max_length=32, blank=True, null=True, help_text=u"Network address. Use address/CIDR notation", verbose_name="Source Address")
+    source = models.CharField(max_length=32, help_text=u"Network address. Use address/CIDR notation", verbose_name="Source Address")
     sourceport = models.ManyToManyField(MatchPort, blank=True, null=True, related_name="matchSourcePort", verbose_name="Source Port")
     destination = models.CharField(max_length=32, help_text=u"Network address. Use address/CIDR notation", verbose_name="Destination Address")
     destinationport = models.ManyToManyField(MatchPort, blank=True, null=True, related_name="matchDestinationPort", verbose_name="Destination Port")
@@ -91,7 +115,7 @@ class Route(models.Model):
     icmpcode = models.CharField(max_length=32, blank=True, null=True, verbose_name="ICMP Code")
     icmptype = models.CharField(max_length=32, blank=True, null=True, verbose_name="ICMP Type")
     packetlength = models.IntegerField(blank=True, null=True, verbose_name="Packet Length")
-    protocol = models.CharField(max_length=32, blank=True, null=True, verbose_name="Protocol")
+    protocol = models.ManyToManyField(MatchProtocol, blank=True, null=True, verbose_name="Protocol")
     tcpflag = models.CharField(max_length=128, blank=True, null=True, verbose_name="TCP flag")
     then = models.ManyToManyField(ThenAction, verbose_name="Then")
     filed = models.DateTimeField(auto_now_add=True)
@@ -239,17 +263,6 @@ class Route(models.Model):
                         logger.info('Icmp type fields do not match')
                 except:
                     pass
-                try:
-                    assert(self.protocol)
-                    assert(devicematch['protocol'][0])
-                    if self.protocol == devicematch['protocol'][0]:
-                        found = found and True
-                        logger.info('Found a matching protocol')
-                    else:
-                        found = False
-                        logger.info('Protocol fields do not match')
-                except:
-                    pass
                 if found and self.status != "ACTIVE":
                     logger.error('Rule is applied on device but appears as offline')
                     self.status = "ACTIVE"
@@ -275,7 +288,7 @@ class Route(models.Model):
     def get_match(self):
         ret = ''
         if self.destination:
-            ret = '%s Dst Addr:<strong>%s</strong><br/>' %(ret, self.destination)
+            ret = '%s Dst Addr:<strong>%s</strong> <br/>' %(ret, self.destination)
         if self.fragmenttype:
             ret = "%s Fragment Type:<strong>%s</strong><br/>" %(ret, self.fragmenttype)
         if self.icmpcode:
@@ -284,24 +297,25 @@ class Route(models.Model):
             ret = "%s ICMP Type:<strong>%s</strong><br/>" %(ret, self.icmptype)
         if self.packetlength:
             ret = "%s Packet Length:<strong>%s</strong><br/>" %(ret, self.packetlength)
-        if self.protocol:
-            ret = "%s Protocol:<strong>%s</strong><br/>" %(ret, self.protocol)
         if self.source:
-            ret = "%s Src Addr:<strong>%s</strong><br/>" %(ret, self.source)
+            ret = "%s Src Addr:<strong>%s</strong> <br/>" %(ret, self.source)
         if self.tcpflag:
             ret = "%s TCP flag:<strong>%s</strong><br/>" %(ret, self.tcpflag)
         if self.port:
             for port in self.port.all():
-                    ret = ret + "Port:<strong>%s</strong><br/>" %(port)
+                    ret = ret + "Port:<strong>%s</strong> <br/>" %(port)
+        if self.protocol:
+            for protocol in self.protocol.all():
+                    ret = ret + "Protocol:<strong>%s</strong> <br/>" %(protocol)
         if self.destinationport:
             for port in self.destinationport.all():
-                    ret = ret + "Dst Port:<strong>%s</strong><br/>" %(port)
+                    ret = ret + "Dst Port:<strong>%s</strong> <br/>" %(port)
         if self.sourceport:
             for port in self.sourceport.all():
-                    ret = ret +"Src Port:<strong>%s</strong><br/>" %(port)
+                    ret = ret +"Src Port:<strong>%s</strong> <br/>" %(port)
         if self.dscp:
             for dscp in self.dscp.all():
-                    ret = ret + "%s Port:<strong>%s</strong><br/>" %(ret, dscp)
+                    ret = ret + "%s Port:<strong>%s</strong> <br/>" %(ret, dscp)
         return ret.rstrip('<br/>')
         
     get_match.short_description = 'Match statement'
@@ -317,7 +331,7 @@ class Route(models.Model):
     
     @property
     def days_to_expire(self):
-        if self.status not in ['EXPIRED', 'ADMININACTIVE', 'ERROR']:
+        if self.status not in ['EXPIRED', 'ADMININACTIVE', 'ERROR', 'INACTIVE']:
             expiration_days = (self.expires - datetime.date.today()).days
             if expiration_days < settings.EXPIRATION_NOTIFY_DAYS:
                 return "%s" %expiration_days