Statistics
| Branch: | Tag: | Revision:

root / flowspec / models.py @ abad126d

History | View | Annotate | Download (13.3 kB)

1 478173ac Leonidas Poulopoulos
# -*- coding: utf-8 -*- vim:encoding=utf-8:
2 478173ac Leonidas Poulopoulos
# vim: tabstop=4:shiftwidth=4:softtabstop=4:expandtab
3 478173ac Leonidas Poulopoulos
4 a3af8464 Leonidas Poulopoulos
from django.db import models
5 b10e01d6 Leonidas Poulopoulos
from django.conf import settings
6 a3af8464 Leonidas Poulopoulos
from django.contrib.auth.models import User
7 357d48dc Leonidas Poulopoulos
from utils import proxy as PR
8 478173ac Leonidas Poulopoulos
from ipaddr import *
9 c1509909 Leonidas Poulopoulos
import datetime
10 357d48dc Leonidas Poulopoulos
import logging
11 9cad4715 Leonidas Poulopoulos
from flowspec.tasks import *
12 9cad4715 Leonidas Poulopoulos
from time import sleep
13 357d48dc Leonidas Poulopoulos
14 f57f6e68 Leonidas Poulopoulos
import beanstalkc
15 97e42c7d Leonidas Poulopoulos
from flowspy.utils.randomizer import id_generator as id_gen
16 3e99e2d1 Leonidas Poulopoulos
17 3e99e2d1 Leonidas Poulopoulos
18 357d48dc Leonidas Poulopoulos
FORMAT = '%(asctime)s %(levelname)s: %(message)s'
19 357d48dc Leonidas Poulopoulos
logging.basicConfig(format=FORMAT)
20 357d48dc Leonidas Poulopoulos
logger = logging.getLogger(__name__)
21 357d48dc Leonidas Poulopoulos
logger.setLevel(logging.DEBUG)
22 357d48dc Leonidas Poulopoulos
23 a24fbf37 Leonidas Poulopoulos
24 a3af8464 Leonidas Poulopoulos
FRAGMENT_CODES = (
25 a3af8464 Leonidas Poulopoulos
    ("dont-fragment", "Don't fragment"),
26 a3af8464 Leonidas Poulopoulos
    ("first-fragment", "First fragment"),
27 a3af8464 Leonidas Poulopoulos
    ("is-fragment", "Is fragment"),
28 a3af8464 Leonidas Poulopoulos
    ("last-fragment", "Last fragment"),
29 a3af8464 Leonidas Poulopoulos
    ("not-a-fragment", "Not a fragment")
30 a3af8464 Leonidas Poulopoulos
)
31 a3af8464 Leonidas Poulopoulos
32 a3af8464 Leonidas Poulopoulos
THEN_CHOICES = (
33 a3af8464 Leonidas Poulopoulos
    ("accept", "Accept"),
34 a3af8464 Leonidas Poulopoulos
    ("discard", "Discard"),
35 a3af8464 Leonidas Poulopoulos
    ("community", "Community"),
36 a3af8464 Leonidas Poulopoulos
    ("next-term", "Next term"),
37 a3af8464 Leonidas Poulopoulos
    ("routing-instance", "Routing Instance"),
38 a3af8464 Leonidas Poulopoulos
    ("rate-limit", "Rate limit"),
39 a3af8464 Leonidas Poulopoulos
    ("sample", "Sample")                
40 a3af8464 Leonidas Poulopoulos
)
41 a3af8464 Leonidas Poulopoulos
42 97e42c7d Leonidas Poulopoulos
ROUTE_STATES = (
43 97e42c7d Leonidas Poulopoulos
    ("ACTIVE", "ACTIVE"),
44 97e42c7d Leonidas Poulopoulos
    ("ERROR", "ERROR"),
45 97e42c7d Leonidas Poulopoulos
    ("EXPIRED", "EXPIRED"),
46 97e42c7d Leonidas Poulopoulos
    ("PENDING", "PENDING"),
47 97e42c7d Leonidas Poulopoulos
    ("OUTOFSYNC", "OUTOFSYNC"),
48 d50fd7b6 Leonidas Poulopoulos
    ("INACTIVE", "INACTIVE"),
49 d50fd7b6 Leonidas Poulopoulos
    ("ADMININACTIVE", "ADMININACTIVE"),           
50 97e42c7d Leonidas Poulopoulos
)
51 97e42c7d Leonidas Poulopoulos
52 a3af8464 Leonidas Poulopoulos
53 c1509909 Leonidas Poulopoulos
def days_offset(): return datetime.date.today() + datetime.timedelta(days = settings.EXPIRATION_DAYS_OFFSET)
54 a3af8464 Leonidas Poulopoulos
    
55 a3af8464 Leonidas Poulopoulos
class MatchPort(models.Model):
56 97e42c7d Leonidas Poulopoulos
    port = models.CharField(max_length=24, unique=True)
57 a24fbf37 Leonidas Poulopoulos
    def __unicode__(self):
58 a24fbf37 Leonidas Poulopoulos
        return self.port
59 a3af8464 Leonidas Poulopoulos
    class Meta:
60 a3af8464 Leonidas Poulopoulos
        db_table = u'match_port'    
61 a3af8464 Leonidas Poulopoulos
62 a3af8464 Leonidas Poulopoulos
class MatchDscp(models.Model):
63 a3af8464 Leonidas Poulopoulos
    dscp = models.CharField(max_length=24)
64 a24fbf37 Leonidas Poulopoulos
    def __unicode__(self):
65 a24fbf37 Leonidas Poulopoulos
        return self.dscp
66 a3af8464 Leonidas Poulopoulos
    class Meta:
67 a3af8464 Leonidas Poulopoulos
        db_table = u'match_dscp'
68 a3af8464 Leonidas Poulopoulos
69 7a8a4da4 Leonidas Poulopoulos
   
70 a3af8464 Leonidas Poulopoulos
class ThenAction(models.Model):
71 b10e01d6 Leonidas Poulopoulos
    action = models.CharField(max_length=60, choices=THEN_CHOICES, verbose_name="Action")
72 b10e01d6 Leonidas Poulopoulos
    action_value = models.CharField(max_length=255, blank=True, null=True, verbose_name="Action Value")
73 a24fbf37 Leonidas Poulopoulos
    def __unicode__(self):
74 97e42c7d Leonidas Poulopoulos
        ret = "%s:%s" %(self.action, self.action_value)
75 97e42c7d Leonidas Poulopoulos
        return ret.rstrip(":")
76 a3af8464 Leonidas Poulopoulos
    class Meta:
77 a3af8464 Leonidas Poulopoulos
        db_table = u'then_action'
78 fdc3d663 Leonidas Poulopoulos
        ordering = ['action', 'action_value']
79 f12b3d54 Leonidas Poulopoulos
        unique_together = ("action", "action_value")
80 a3af8464 Leonidas Poulopoulos
81 a3af8464 Leonidas Poulopoulos
class Route(models.Model):
82 971645d6 Leonidas Poulopoulos
    name = models.SlugField(max_length=128)
83 9cad4715 Leonidas Poulopoulos
    applier = models.ForeignKey(User, blank=True, null=True)
84 abad126d Leonidas Poulopoulos
    source = models.CharField(max_length=32, help_text=u"Network address. Use address/CIDR notation", verbose_name="Source Address")
85 b10e01d6 Leonidas Poulopoulos
    sourceport = models.ManyToManyField(MatchPort, blank=True, null=True, related_name="matchSourcePort", verbose_name="Source Port")
86 971645d6 Leonidas Poulopoulos
    destination = models.CharField(max_length=32, help_text=u"Network address. Use address/CIDR notation", verbose_name="Destination Address")
87 b10e01d6 Leonidas Poulopoulos
    destinationport = models.ManyToManyField(MatchPort, blank=True, null=True, related_name="matchDestinationPort", verbose_name="Destination Port")
88 b10e01d6 Leonidas Poulopoulos
    port = models.ManyToManyField(MatchPort, blank=True, null=True, related_name="matchPort", verbose_name="Port" )
89 b10e01d6 Leonidas Poulopoulos
    dscp = models.ManyToManyField(MatchDscp, blank=True, null=True, verbose_name="DSCP")
90 b10e01d6 Leonidas Poulopoulos
    fragmenttype = models.CharField(max_length=20, choices=FRAGMENT_CODES, blank=True, null=True, verbose_name="Fragment Type")
91 b10e01d6 Leonidas Poulopoulos
    icmpcode = models.CharField(max_length=32, blank=True, null=True, verbose_name="ICMP Code")
92 b10e01d6 Leonidas Poulopoulos
    icmptype = models.CharField(max_length=32, blank=True, null=True, verbose_name="ICMP Type")
93 b10e01d6 Leonidas Poulopoulos
    packetlength = models.IntegerField(blank=True, null=True, verbose_name="Packet Length")
94 b10e01d6 Leonidas Poulopoulos
    protocol = models.CharField(max_length=32, blank=True, null=True, verbose_name="Protocol")
95 b10e01d6 Leonidas Poulopoulos
    tcpflag = models.CharField(max_length=128, blank=True, null=True, verbose_name="TCP flag")
96 b10e01d6 Leonidas Poulopoulos
    then = models.ManyToManyField(ThenAction, verbose_name="Then")
97 a3af8464 Leonidas Poulopoulos
    filed = models.DateTimeField(auto_now_add=True)
98 a3af8464 Leonidas Poulopoulos
    last_updated = models.DateTimeField(auto_now=True)
99 97e42c7d Leonidas Poulopoulos
    status = models.CharField(max_length=20, choices=ROUTE_STATES, blank=True, null=True, verbose_name="Status", default="PENDING")
100 97e42c7d Leonidas Poulopoulos
#    is_online = models.BooleanField(default=False)
101 97e42c7d Leonidas Poulopoulos
#    is_active = models.BooleanField(default=False)
102 052c14aa Leonidas Poulopoulos
    expires = models.DateField(default=days_offset)
103 357d48dc Leonidas Poulopoulos
    response = models.CharField(max_length=512, blank=True, null=True)
104 b10e01d6 Leonidas Poulopoulos
    comments = models.TextField(null=True, blank=True, verbose_name="Comments")
105 357d48dc Leonidas Poulopoulos
106 357d48dc Leonidas Poulopoulos
    
107 a24fbf37 Leonidas Poulopoulos
    def __unicode__(self):
108 a24fbf37 Leonidas Poulopoulos
        return self.name
109 a24fbf37 Leonidas Poulopoulos
    
110 a3af8464 Leonidas Poulopoulos
    class Meta:
111 a24fbf37 Leonidas Poulopoulos
        db_table = u'route'
112 7d408f6f Leonidas Poulopoulos
        verbose_name = "Rule"
113 7d408f6f Leonidas Poulopoulos
        verbose_name_plural = "Rules"
114 7a8a4da4 Leonidas Poulopoulos
    
115 97e42c7d Leonidas Poulopoulos
    def save(self, *args, **kwargs):
116 97e42c7d Leonidas Poulopoulos
        if not self.pk:
117 97e42c7d Leonidas Poulopoulos
            hash = id_gen()
118 97e42c7d Leonidas Poulopoulos
            self.name = "%s_%s" %(self.name, hash)
119 97e42c7d Leonidas Poulopoulos
        super(Route, self).save(*args, **kwargs) # Call the "real" save() method.
120 97e42c7d Leonidas Poulopoulos
121 97e42c7d Leonidas Poulopoulos
        
122 7a8a4da4 Leonidas Poulopoulos
    def clean(self, *args, **kwargs):
123 7a8a4da4 Leonidas Poulopoulos
        from django.core.exceptions import ValidationError
124 7a8a4da4 Leonidas Poulopoulos
        if self.destination:
125 7a8a4da4 Leonidas Poulopoulos
            try:
126 b10e01d6 Leonidas Poulopoulos
                address = IPNetwork(self.destination)
127 b10e01d6 Leonidas Poulopoulos
                self.destination = address.exploded
128 7a8a4da4 Leonidas Poulopoulos
            except Exception:
129 b10e01d6 Leonidas Poulopoulos
                raise ValidationError('Invalid network address format at Destination Field')
130 7a8a4da4 Leonidas Poulopoulos
        if self.source:
131 7a8a4da4 Leonidas Poulopoulos
            try:
132 b10e01d6 Leonidas Poulopoulos
                address = IPNetwork(self.source)
133 b10e01d6 Leonidas Poulopoulos
                self.source = address.exploded
134 7a8a4da4 Leonidas Poulopoulos
            except Exception:
135 b10e01d6 Leonidas Poulopoulos
                raise ValidationError('Invalid network address format at Source Field')
136 6a946adf Leonidas Poulopoulos
   
137 9cad4715 Leonidas Poulopoulos
    def commit_add(self, *args, **kwargs):
138 97e42c7d Leonidas Poulopoulos
        peer = self.applier.get_profile().peer.domain_name
139 933c1f31 Leonidas Poulopoulos
        send_message("[%s] Adding rule %s. Please wait..." %(self.applier.username, self.name), peer)
140 9cad4715 Leonidas Poulopoulos
        response = add.delay(self)
141 6a946adf Leonidas Poulopoulos
        logger.info("Got add job id: %s" %response)
142 9cad4715 Leonidas Poulopoulos
        
143 3e99e2d1 Leonidas Poulopoulos
    def commit_edit(self, *args, **kwargs):
144 97e42c7d Leonidas Poulopoulos
        peer = self.applier.get_profile().peer.domain_name
145 933c1f31 Leonidas Poulopoulos
        send_message("[%s] Editing rule %s. Please wait..." %(self.applier.username, self.name), peer)
146 3e99e2d1 Leonidas Poulopoulos
        response = edit.delay(self)
147 3e99e2d1 Leonidas Poulopoulos
        logger.info("Got edit job id: %s" %response)
148 b10e01d6 Leonidas Poulopoulos
149 3e99e2d1 Leonidas Poulopoulos
    def commit_delete(self, *args, **kwargs):
150 6a946adf Leonidas Poulopoulos
        reason_text = ''
151 049a5a10 Leonidas Poulopoulos
        reason = ''
152 6a946adf Leonidas Poulopoulos
        if "reason" in kwargs:
153 6a946adf Leonidas Poulopoulos
            reason = kwargs['reason']
154 6a946adf Leonidas Poulopoulos
            reason_text = "Reason: %s. " %reason
155 97e42c7d Leonidas Poulopoulos
        peer = self.applier.get_profile().peer.domain_name
156 61e178c3 Leonidas Poulopoulos
        send_message("[%s] Suspending rule %s. %sPlease wait..." %(self.applier.username, self.name, reason_text), peer)
157 6a946adf Leonidas Poulopoulos
        response = delete.delay(self, reason=reason)
158 6a946adf Leonidas Poulopoulos
        logger.info("Got delete job id: %s" %response)
159 6a946adf Leonidas Poulopoulos
160 c1509909 Leonidas Poulopoulos
    def has_expired(self):
161 c1509909 Leonidas Poulopoulos
        today = datetime.date.today()
162 c1509909 Leonidas Poulopoulos
        if today > self.expires:
163 c1509909 Leonidas Poulopoulos
            return True
164 c1509909 Leonidas Poulopoulos
        return False
165 6a946adf Leonidas Poulopoulos
    
166 6a946adf Leonidas Poulopoulos
    def check_sync(self):
167 6a946adf Leonidas Poulopoulos
        if not self.is_synced():
168 6a946adf Leonidas Poulopoulos
            self.status = "OUTOFSYNC"
169 6a946adf Leonidas Poulopoulos
            self.save()
170 6a946adf Leonidas Poulopoulos
    
171 6a946adf Leonidas Poulopoulos
    def is_synced(self):
172 357d48dc Leonidas Poulopoulos
        found = False
173 357d48dc Leonidas Poulopoulos
        get_device = PR.Retriever()
174 357d48dc Leonidas Poulopoulos
        device = get_device.fetch_device()
175 357d48dc Leonidas Poulopoulos
        try:
176 357d48dc Leonidas Poulopoulos
            routes = device.routing_options[0].routes
177 357d48dc Leonidas Poulopoulos
        except Exception as e:
178 97e42c7d Leonidas Poulopoulos
            self.status = "EXPIRED"
179 971645d6 Leonidas Poulopoulos
            self.save()
180 357d48dc Leonidas Poulopoulos
            logger.error("No routing options on device. Exception: %s" %e)
181 6a946adf Leonidas Poulopoulos
            return True
182 357d48dc Leonidas Poulopoulos
        for route in routes:
183 357d48dc Leonidas Poulopoulos
            if route.name == self.name:
184 357d48dc Leonidas Poulopoulos
                found = True
185 933c1f31 Leonidas Poulopoulos
                logger.info('Found a matching rule name')
186 357d48dc Leonidas Poulopoulos
                devicematch = route.match
187 357d48dc Leonidas Poulopoulos
                try:
188 b10e01d6 Leonidas Poulopoulos
                    assert(self.destination)
189 357d48dc Leonidas Poulopoulos
                    assert(devicematch['destination'][0])
190 b10e01d6 Leonidas Poulopoulos
                    if self.destination == devicematch['destination'][0]:
191 357d48dc Leonidas Poulopoulos
                        found = found and True
192 357d48dc Leonidas Poulopoulos
                        logger.info('Found a matching destination')
193 357d48dc Leonidas Poulopoulos
                    else:
194 357d48dc Leonidas Poulopoulos
                        found = False
195 357d48dc Leonidas Poulopoulos
                        logger.info('Destination fields do not match')
196 357d48dc Leonidas Poulopoulos
                except:
197 357d48dc Leonidas Poulopoulos
                    pass
198 357d48dc Leonidas Poulopoulos
                try:
199 b10e01d6 Leonidas Poulopoulos
                    assert(self.source)
200 357d48dc Leonidas Poulopoulos
                    assert(devicematch['source'][0])
201 b10e01d6 Leonidas Poulopoulos
                    if self.source == devicematch['source'][0]:
202 357d48dc Leonidas Poulopoulos
                        found = found and True
203 357d48dc Leonidas Poulopoulos
                        logger.info('Found a matching source')
204 357d48dc Leonidas Poulopoulos
                    else:
205 357d48dc Leonidas Poulopoulos
                        found = False
206 357d48dc Leonidas Poulopoulos
                        logger.info('Source fields do not match')
207 357d48dc Leonidas Poulopoulos
                except:
208 357d48dc Leonidas Poulopoulos
                    pass
209 357d48dc Leonidas Poulopoulos
                try:
210 b10e01d6 Leonidas Poulopoulos
                    assert(self.fragmenttype)
211 357d48dc Leonidas Poulopoulos
                    assert(devicematch['fragment'][0])
212 b10e01d6 Leonidas Poulopoulos
                    if self.fragmenttype == devicematch['fragment'][0]:
213 357d48dc Leonidas Poulopoulos
                        found = found and True
214 357d48dc Leonidas Poulopoulos
                        logger.info('Found a matching fragment type')
215 357d48dc Leonidas Poulopoulos
                    else:
216 357d48dc Leonidas Poulopoulos
                        found = False
217 357d48dc Leonidas Poulopoulos
                        logger.info('Fragment type fields do not match')
218 357d48dc Leonidas Poulopoulos
                except:
219 357d48dc Leonidas Poulopoulos
                    pass
220 357d48dc Leonidas Poulopoulos
                try:
221 b10e01d6 Leonidas Poulopoulos
                    assert(self.icmpcode)
222 357d48dc Leonidas Poulopoulos
                    assert(devicematch['icmp-code'][0])
223 b10e01d6 Leonidas Poulopoulos
                    if self.icmpcode == devicematch['icmp-code'][0]:
224 357d48dc Leonidas Poulopoulos
                        found = found and True
225 357d48dc Leonidas Poulopoulos
                        logger.info('Found a matching icmp code')
226 357d48dc Leonidas Poulopoulos
                    else:
227 357d48dc Leonidas Poulopoulos
                        found = False
228 357d48dc Leonidas Poulopoulos
                        logger.info('Icmp code fields do not match')
229 357d48dc Leonidas Poulopoulos
                except:
230 357d48dc Leonidas Poulopoulos
                    pass
231 357d48dc Leonidas Poulopoulos
                try:
232 b10e01d6 Leonidas Poulopoulos
                    assert(self.icmptype)
233 357d48dc Leonidas Poulopoulos
                    assert(devicematch['icmp-type'][0])
234 b10e01d6 Leonidas Poulopoulos
                    if self.icmptype == devicematch['icmp-type'][0]:
235 357d48dc Leonidas Poulopoulos
                        found = found and True
236 357d48dc Leonidas Poulopoulos
                        logger.info('Found a matching icmp type')
237 357d48dc Leonidas Poulopoulos
                    else:
238 357d48dc Leonidas Poulopoulos
                        found = False
239 357d48dc Leonidas Poulopoulos
                        logger.info('Icmp type fields do not match')
240 357d48dc Leonidas Poulopoulos
                except:
241 357d48dc Leonidas Poulopoulos
                    pass
242 357d48dc Leonidas Poulopoulos
                try:
243 b10e01d6 Leonidas Poulopoulos
                    assert(self.protocol)
244 357d48dc Leonidas Poulopoulos
                    assert(devicematch['protocol'][0])
245 b10e01d6 Leonidas Poulopoulos
                    if self.protocol == devicematch['protocol'][0]:
246 357d48dc Leonidas Poulopoulos
                        found = found and True
247 357d48dc Leonidas Poulopoulos
                        logger.info('Found a matching protocol')
248 357d48dc Leonidas Poulopoulos
                    else:
249 357d48dc Leonidas Poulopoulos
                        found = False
250 357d48dc Leonidas Poulopoulos
                        logger.info('Protocol fields do not match')
251 357d48dc Leonidas Poulopoulos
                except:
252 357d48dc Leonidas Poulopoulos
                    pass
253 97e42c7d Leonidas Poulopoulos
                if found and self.status != "ACTIVE":
254 e173e7c2 Leonidas Poulopoulos
                    logger.error('Rule is applied on device but appears as offline')
255 e173e7c2 Leonidas Poulopoulos
                    self.status = "ACTIVE"
256 e173e7c2 Leonidas Poulopoulos
                    self.save()
257 e173e7c2 Leonidas Poulopoulos
                    found = True
258 33281310 Leonidas Poulopoulos
            if self.status == "ADMININACTIVE" or self.status == "INACTIVE" or self.status == "EXPIRED":
259 e173e7c2 Leonidas Poulopoulos
                found = True
260 357d48dc Leonidas Poulopoulos
        return found
261 357d48dc Leonidas Poulopoulos
262 357d48dc Leonidas Poulopoulos
    def get_then(self):
263 357d48dc Leonidas Poulopoulos
        ret = ''
264 b10e01d6 Leonidas Poulopoulos
        then_statements = self.then.all()
265 357d48dc Leonidas Poulopoulos
        for statement in then_statements:
266 357d48dc Leonidas Poulopoulos
            if statement.action_value:
267 357d48dc Leonidas Poulopoulos
                ret = "%s %s:<strong>%s</strong><br/>" %(ret, statement.action, statement.action_value)
268 357d48dc Leonidas Poulopoulos
            else: 
269 357d48dc Leonidas Poulopoulos
                ret = "%s %s<br>" %(ret, statement.action)
270 357d48dc Leonidas Poulopoulos
        return ret.rstrip(',')
271 357d48dc Leonidas Poulopoulos
    
272 357d48dc Leonidas Poulopoulos
    get_then.short_description = 'Then statement'
273 357d48dc Leonidas Poulopoulos
    get_then.allow_tags = True
274 b10e01d6 Leonidas Poulopoulos
#
275 357d48dc Leonidas Poulopoulos
    def get_match(self):
276 357d48dc Leonidas Poulopoulos
        ret = ''
277 b10e01d6 Leonidas Poulopoulos
        if self.destination:
278 f5d68f6f Leonidas Poulopoulos
            ret = '%s Dst Addr:<strong>%s</strong> <br/>' %(ret, self.destination)
279 b10e01d6 Leonidas Poulopoulos
        if self.fragmenttype:
280 3e99e2d1 Leonidas Poulopoulos
            ret = "%s Fragment Type:<strong>%s</strong><br/>" %(ret, self.fragmenttype)
281 b10e01d6 Leonidas Poulopoulos
        if self.icmpcode:
282 3e99e2d1 Leonidas Poulopoulos
            ret = "%s ICMP code:<strong>%s</strong><br/>" %(ret, self.icmpcode)
283 b10e01d6 Leonidas Poulopoulos
        if self.icmptype:
284 3e99e2d1 Leonidas Poulopoulos
            ret = "%s ICMP Type:<strong>%s</strong><br/>" %(ret, self.icmptype)
285 b10e01d6 Leonidas Poulopoulos
        if self.packetlength:
286 3e99e2d1 Leonidas Poulopoulos
            ret = "%s Packet Length:<strong>%s</strong><br/>" %(ret, self.packetlength)
287 b10e01d6 Leonidas Poulopoulos
        if self.protocol:
288 3e99e2d1 Leonidas Poulopoulos
            ret = "%s Protocol:<strong>%s</strong><br/>" %(ret, self.protocol)
289 b10e01d6 Leonidas Poulopoulos
        if self.source:
290 f5d68f6f Leonidas Poulopoulos
            ret = "%s Src Addr:<strong>%s</strong> <br/>" %(ret, self.source)
291 b10e01d6 Leonidas Poulopoulos
        if self.tcpflag:
292 3e99e2d1 Leonidas Poulopoulos
            ret = "%s TCP flag:<strong>%s</strong><br/>" %(ret, self.tcpflag)
293 b10e01d6 Leonidas Poulopoulos
        if self.port:
294 b10e01d6 Leonidas Poulopoulos
            for port in self.port.all():
295 f5d68f6f Leonidas Poulopoulos
                    ret = ret + "Port:<strong>%s</strong> <br/>" %(port)
296 b10e01d6 Leonidas Poulopoulos
        if self.destinationport:
297 b10e01d6 Leonidas Poulopoulos
            for port in self.destinationport.all():
298 f5d68f6f Leonidas Poulopoulos
                    ret = ret + "Dst Port:<strong>%s</strong> <br/>" %(port)
299 b10e01d6 Leonidas Poulopoulos
        if self.sourceport:
300 b10e01d6 Leonidas Poulopoulos
            for port in self.sourceport.all():
301 f5d68f6f Leonidas Poulopoulos
                    ret = ret +"Src Port:<strong>%s</strong> <br/>" %(port)
302 b10e01d6 Leonidas Poulopoulos
        if self.dscp:
303 b10e01d6 Leonidas Poulopoulos
            for dscp in self.dscp.all():
304 f5d68f6f Leonidas Poulopoulos
                    ret = ret + "%s Port:<strong>%s</strong> <br/>" %(ret, dscp)
305 357d48dc Leonidas Poulopoulos
        return ret.rstrip('<br/>')
306 357d48dc Leonidas Poulopoulos
        
307 357d48dc Leonidas Poulopoulos
    get_match.short_description = 'Match statement'
308 357d48dc Leonidas Poulopoulos
    get_match.allow_tags = True
309 d50fd7b6 Leonidas Poulopoulos
    
310 d50fd7b6 Leonidas Poulopoulos
    @property
311 d50fd7b6 Leonidas Poulopoulos
    def applier_peer(self):
312 d50fd7b6 Leonidas Poulopoulos
        try:
313 d50fd7b6 Leonidas Poulopoulos
            applier_peer = self.applier.get_profile().peer
314 d50fd7b6 Leonidas Poulopoulos
        except:
315 d50fd7b6 Leonidas Poulopoulos
            applier_peer = None
316 d50fd7b6 Leonidas Poulopoulos
        return applier_peer
317 fb67376a Leonidas Poulopoulos
    
318 fb67376a Leonidas Poulopoulos
    @property
319 fb67376a Leonidas Poulopoulos
    def days_to_expire(self):
320 e74203ca Leonidas Poulopoulos
        if self.status not in ['EXPIRED', 'ADMININACTIVE', 'ERROR', 'INACTIVE']:
321 fb67376a Leonidas Poulopoulos
            expiration_days = (self.expires - datetime.date.today()).days
322 fb67376a Leonidas Poulopoulos
            if expiration_days < settings.EXPIRATION_NOTIFY_DAYS:
323 7c4bc8de Leonidas Poulopoulos
                return "%s" %expiration_days
324 fb67376a Leonidas Poulopoulos
            else:
325 fb67376a Leonidas Poulopoulos
                return False
326 fb67376a Leonidas Poulopoulos
        else:
327 fb67376a Leonidas Poulopoulos
            return False
328 357d48dc Leonidas Poulopoulos
329 25d08a62 Leonidas Poulopoulos
def send_message(msg, user):
330 97e42c7d Leonidas Poulopoulos
#    username = user.username
331 97e42c7d Leonidas Poulopoulos
    peer = user
332 3e99e2d1 Leonidas Poulopoulos
    b = beanstalkc.Connection()
333 3e99e2d1 Leonidas Poulopoulos
    b.use(settings.POLLS_TUBE)
334 97e42c7d Leonidas Poulopoulos
    tube_message = json.dumps({'message': str(msg), 'username':peer})
335 25d08a62 Leonidas Poulopoulos
    b.put(tube_message)
336 3e99e2d1 Leonidas Poulopoulos
    b.close()