Statistics
| Branch: | Tag: | Revision:

root / flowspec / models.py @ fb67376a

History | View | Annotate | Download (13.2 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 3e99e2d1 Leonidas Poulopoulos
from flowspy.utils 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 a3af8464 Leonidas Poulopoulos
79 a3af8464 Leonidas Poulopoulos
class Route(models.Model):
80 971645d6 Leonidas Poulopoulos
    name = models.SlugField(max_length=128)
81 9cad4715 Leonidas Poulopoulos
    applier = models.ForeignKey(User, blank=True, null=True)
82 b10e01d6 Leonidas Poulopoulos
    source = models.CharField(max_length=32, blank=True, null=True, help_text=u"Network address. Use address/CIDR notation", verbose_name="Source Address")
83 b10e01d6 Leonidas Poulopoulos
    sourceport = models.ManyToManyField(MatchPort, blank=True, null=True, related_name="matchSourcePort", verbose_name="Source Port")
84 971645d6 Leonidas Poulopoulos
    destination = models.CharField(max_length=32, help_text=u"Network address. Use address/CIDR notation", verbose_name="Destination Address")
85 b10e01d6 Leonidas Poulopoulos
    destinationport = models.ManyToManyField(MatchPort, blank=True, null=True, related_name="matchDestinationPort", verbose_name="Destination Port")
86 b10e01d6 Leonidas Poulopoulos
    port = models.ManyToManyField(MatchPort, blank=True, null=True, related_name="matchPort", verbose_name="Port" )
87 b10e01d6 Leonidas Poulopoulos
    dscp = models.ManyToManyField(MatchDscp, blank=True, null=True, verbose_name="DSCP")
88 b10e01d6 Leonidas Poulopoulos
    fragmenttype = models.CharField(max_length=20, choices=FRAGMENT_CODES, blank=True, null=True, verbose_name="Fragment Type")
89 b10e01d6 Leonidas Poulopoulos
    icmpcode = models.CharField(max_length=32, blank=True, null=True, verbose_name="ICMP Code")
90 b10e01d6 Leonidas Poulopoulos
    icmptype = models.CharField(max_length=32, blank=True, null=True, verbose_name="ICMP Type")
91 b10e01d6 Leonidas Poulopoulos
    packetlength = models.IntegerField(blank=True, null=True, verbose_name="Packet Length")
92 b10e01d6 Leonidas Poulopoulos
    protocol = models.CharField(max_length=32, blank=True, null=True, verbose_name="Protocol")
93 b10e01d6 Leonidas Poulopoulos
    tcpflag = models.CharField(max_length=128, blank=True, null=True, verbose_name="TCP flag")
94 b10e01d6 Leonidas Poulopoulos
    then = models.ManyToManyField(ThenAction, verbose_name="Then")
95 a3af8464 Leonidas Poulopoulos
    filed = models.DateTimeField(auto_now_add=True)
96 a3af8464 Leonidas Poulopoulos
    last_updated = models.DateTimeField(auto_now=True)
97 97e42c7d Leonidas Poulopoulos
    status = models.CharField(max_length=20, choices=ROUTE_STATES, blank=True, null=True, verbose_name="Status", default="PENDING")
98 97e42c7d Leonidas Poulopoulos
#    is_online = models.BooleanField(default=False)
99 97e42c7d Leonidas Poulopoulos
#    is_active = models.BooleanField(default=False)
100 052c14aa Leonidas Poulopoulos
    expires = models.DateField(default=days_offset)
101 357d48dc Leonidas Poulopoulos
    response = models.CharField(max_length=512, blank=True, null=True)
102 b10e01d6 Leonidas Poulopoulos
    comments = models.TextField(null=True, blank=True, verbose_name="Comments")
103 357d48dc Leonidas Poulopoulos
104 357d48dc Leonidas Poulopoulos
    
105 a24fbf37 Leonidas Poulopoulos
    def __unicode__(self):
106 a24fbf37 Leonidas Poulopoulos
        return self.name
107 a24fbf37 Leonidas Poulopoulos
    
108 a3af8464 Leonidas Poulopoulos
    class Meta:
109 a24fbf37 Leonidas Poulopoulos
        db_table = u'route'
110 7d408f6f Leonidas Poulopoulos
        verbose_name = "Rule"
111 7d408f6f Leonidas Poulopoulos
        verbose_name_plural = "Rules"
112 7a8a4da4 Leonidas Poulopoulos
    
113 97e42c7d Leonidas Poulopoulos
    def save(self, *args, **kwargs):
114 97e42c7d Leonidas Poulopoulos
        if not self.pk:
115 97e42c7d Leonidas Poulopoulos
            hash = id_gen()
116 97e42c7d Leonidas Poulopoulos
            self.name = "%s_%s" %(self.name, hash)
117 97e42c7d Leonidas Poulopoulos
        super(Route, self).save(*args, **kwargs) # Call the "real" save() method.
118 97e42c7d Leonidas Poulopoulos
119 97e42c7d Leonidas Poulopoulos
        
120 7a8a4da4 Leonidas Poulopoulos
    def clean(self, *args, **kwargs):
121 7a8a4da4 Leonidas Poulopoulos
        from django.core.exceptions import ValidationError
122 7a8a4da4 Leonidas Poulopoulos
        if self.destination:
123 7a8a4da4 Leonidas Poulopoulos
            try:
124 b10e01d6 Leonidas Poulopoulos
                address = IPNetwork(self.destination)
125 b10e01d6 Leonidas Poulopoulos
                self.destination = address.exploded
126 7a8a4da4 Leonidas Poulopoulos
            except Exception:
127 b10e01d6 Leonidas Poulopoulos
                raise ValidationError('Invalid network address format at Destination Field')
128 7a8a4da4 Leonidas Poulopoulos
        if self.source:
129 7a8a4da4 Leonidas Poulopoulos
            try:
130 b10e01d6 Leonidas Poulopoulos
                address = IPNetwork(self.source)
131 b10e01d6 Leonidas Poulopoulos
                self.source = address.exploded
132 7a8a4da4 Leonidas Poulopoulos
            except Exception:
133 b10e01d6 Leonidas Poulopoulos
                raise ValidationError('Invalid network address format at Source Field')
134 6a946adf Leonidas Poulopoulos
   
135 9cad4715 Leonidas Poulopoulos
    def commit_add(self, *args, **kwargs):
136 97e42c7d Leonidas Poulopoulos
        peer = self.applier.get_profile().peer.domain_name
137 97e42c7d Leonidas Poulopoulos
        send_message("[%s] Adding route %s. Please wait..." %(self.applier.username, self.name), peer)
138 9cad4715 Leonidas Poulopoulos
        response = add.delay(self)
139 6a946adf Leonidas Poulopoulos
        logger.info("Got add job id: %s" %response)
140 9cad4715 Leonidas Poulopoulos
        
141 3e99e2d1 Leonidas Poulopoulos
    def commit_edit(self, *args, **kwargs):
142 97e42c7d Leonidas Poulopoulos
        peer = self.applier.get_profile().peer.domain_name
143 97e42c7d Leonidas Poulopoulos
        send_message("[%s] Editing route %s. Please wait..." %(self.applier.username, self.name), peer)
144 3e99e2d1 Leonidas Poulopoulos
        response = edit.delay(self)
145 3e99e2d1 Leonidas Poulopoulos
        logger.info("Got edit job id: %s" %response)
146 b10e01d6 Leonidas Poulopoulos
147 3e99e2d1 Leonidas Poulopoulos
    def commit_delete(self, *args, **kwargs):
148 6a946adf Leonidas Poulopoulos
        reason_text = ''
149 049a5a10 Leonidas Poulopoulos
        reason = ''
150 6a946adf Leonidas Poulopoulos
        if "reason" in kwargs:
151 6a946adf Leonidas Poulopoulos
            reason = kwargs['reason']
152 6a946adf Leonidas Poulopoulos
            reason_text = "Reason: %s. " %reason
153 97e42c7d Leonidas Poulopoulos
        peer = self.applier.get_profile().peer.domain_name
154 049a5a10 Leonidas Poulopoulos
        send_message("[%s] Removing route %s. %sPlease wait..." %(self.applier.username, self.name, reason_text), peer)
155 6a946adf Leonidas Poulopoulos
        response = delete.delay(self, reason=reason)
156 6a946adf Leonidas Poulopoulos
        logger.info("Got delete job id: %s" %response)
157 6a946adf Leonidas Poulopoulos
158 c1509909 Leonidas Poulopoulos
    def has_expired(self):
159 c1509909 Leonidas Poulopoulos
        today = datetime.date.today()
160 c1509909 Leonidas Poulopoulos
        if today > self.expires:
161 c1509909 Leonidas Poulopoulos
            return True
162 c1509909 Leonidas Poulopoulos
        return False
163 6a946adf Leonidas Poulopoulos
    
164 6a946adf Leonidas Poulopoulos
    def check_sync(self):
165 6a946adf Leonidas Poulopoulos
        if not self.is_synced():
166 6a946adf Leonidas Poulopoulos
            self.status = "OUTOFSYNC"
167 6a946adf Leonidas Poulopoulos
            self.save()
168 6a946adf Leonidas Poulopoulos
    
169 6a946adf Leonidas Poulopoulos
    def is_synced(self):
170 357d48dc Leonidas Poulopoulos
        found = False
171 357d48dc Leonidas Poulopoulos
        get_device = PR.Retriever()
172 357d48dc Leonidas Poulopoulos
        device = get_device.fetch_device()
173 357d48dc Leonidas Poulopoulos
        try:
174 357d48dc Leonidas Poulopoulos
            routes = device.routing_options[0].routes
175 357d48dc Leonidas Poulopoulos
        except Exception as e:
176 97e42c7d Leonidas Poulopoulos
            self.status = "EXPIRED"
177 971645d6 Leonidas Poulopoulos
            self.save()
178 357d48dc Leonidas Poulopoulos
            logger.error("No routing options on device. Exception: %s" %e)
179 6a946adf Leonidas Poulopoulos
            return True
180 357d48dc Leonidas Poulopoulos
        for route in routes:
181 357d48dc Leonidas Poulopoulos
            if route.name == self.name:
182 357d48dc Leonidas Poulopoulos
                found = True
183 357d48dc Leonidas Poulopoulos
                logger.info('Found a matching route name')
184 357d48dc Leonidas Poulopoulos
                devicematch = route.match
185 357d48dc Leonidas Poulopoulos
                try:
186 b10e01d6 Leonidas Poulopoulos
                    assert(self.destination)
187 357d48dc Leonidas Poulopoulos
                    assert(devicematch['destination'][0])
188 b10e01d6 Leonidas Poulopoulos
                    if self.destination == devicematch['destination'][0]:
189 357d48dc Leonidas Poulopoulos
                        found = found and True
190 357d48dc Leonidas Poulopoulos
                        logger.info('Found a matching destination')
191 357d48dc Leonidas Poulopoulos
                    else:
192 357d48dc Leonidas Poulopoulos
                        found = False
193 357d48dc Leonidas Poulopoulos
                        logger.info('Destination fields do not match')
194 357d48dc Leonidas Poulopoulos
                except:
195 357d48dc Leonidas Poulopoulos
                    pass
196 357d48dc Leonidas Poulopoulos
                try:
197 b10e01d6 Leonidas Poulopoulos
                    assert(self.source)
198 357d48dc Leonidas Poulopoulos
                    assert(devicematch['source'][0])
199 b10e01d6 Leonidas Poulopoulos
                    if self.source == devicematch['source'][0]:
200 357d48dc Leonidas Poulopoulos
                        found = found and True
201 357d48dc Leonidas Poulopoulos
                        logger.info('Found a matching source')
202 357d48dc Leonidas Poulopoulos
                    else:
203 357d48dc Leonidas Poulopoulos
                        found = False
204 357d48dc Leonidas Poulopoulos
                        logger.info('Source fields do not match')
205 357d48dc Leonidas Poulopoulos
                except:
206 357d48dc Leonidas Poulopoulos
                    pass
207 357d48dc Leonidas Poulopoulos
                try:
208 b10e01d6 Leonidas Poulopoulos
                    assert(self.fragmenttype)
209 357d48dc Leonidas Poulopoulos
                    assert(devicematch['fragment'][0])
210 b10e01d6 Leonidas Poulopoulos
                    if self.fragmenttype == devicematch['fragment'][0]:
211 357d48dc Leonidas Poulopoulos
                        found = found and True
212 357d48dc Leonidas Poulopoulos
                        logger.info('Found a matching fragment type')
213 357d48dc Leonidas Poulopoulos
                    else:
214 357d48dc Leonidas Poulopoulos
                        found = False
215 357d48dc Leonidas Poulopoulos
                        logger.info('Fragment type fields do not match')
216 357d48dc Leonidas Poulopoulos
                except:
217 357d48dc Leonidas Poulopoulos
                    pass
218 357d48dc Leonidas Poulopoulos
                try:
219 b10e01d6 Leonidas Poulopoulos
                    assert(self.icmpcode)
220 357d48dc Leonidas Poulopoulos
                    assert(devicematch['icmp-code'][0])
221 b10e01d6 Leonidas Poulopoulos
                    if self.icmpcode == devicematch['icmp-code'][0]:
222 357d48dc Leonidas Poulopoulos
                        found = found and True
223 357d48dc Leonidas Poulopoulos
                        logger.info('Found a matching icmp code')
224 357d48dc Leonidas Poulopoulos
                    else:
225 357d48dc Leonidas Poulopoulos
                        found = False
226 357d48dc Leonidas Poulopoulos
                        logger.info('Icmp code fields do not match')
227 357d48dc Leonidas Poulopoulos
                except:
228 357d48dc Leonidas Poulopoulos
                    pass
229 357d48dc Leonidas Poulopoulos
                try:
230 b10e01d6 Leonidas Poulopoulos
                    assert(self.icmptype)
231 357d48dc Leonidas Poulopoulos
                    assert(devicematch['icmp-type'][0])
232 b10e01d6 Leonidas Poulopoulos
                    if self.icmptype == devicematch['icmp-type'][0]:
233 357d48dc Leonidas Poulopoulos
                        found = found and True
234 357d48dc Leonidas Poulopoulos
                        logger.info('Found a matching icmp type')
235 357d48dc Leonidas Poulopoulos
                    else:
236 357d48dc Leonidas Poulopoulos
                        found = False
237 357d48dc Leonidas Poulopoulos
                        logger.info('Icmp type fields do not match')
238 357d48dc Leonidas Poulopoulos
                except:
239 357d48dc Leonidas Poulopoulos
                    pass
240 357d48dc Leonidas Poulopoulos
                try:
241 b10e01d6 Leonidas Poulopoulos
                    assert(self.protocol)
242 357d48dc Leonidas Poulopoulos
                    assert(devicematch['protocol'][0])
243 b10e01d6 Leonidas Poulopoulos
                    if self.protocol == devicematch['protocol'][0]:
244 357d48dc Leonidas Poulopoulos
                        found = found and True
245 357d48dc Leonidas Poulopoulos
                        logger.info('Found a matching protocol')
246 357d48dc Leonidas Poulopoulos
                    else:
247 357d48dc Leonidas Poulopoulos
                        found = False
248 357d48dc Leonidas Poulopoulos
                        logger.info('Protocol fields do not match')
249 357d48dc Leonidas Poulopoulos
                except:
250 357d48dc Leonidas Poulopoulos
                    pass
251 97e42c7d Leonidas Poulopoulos
                if found and self.status != "ACTIVE":
252 e173e7c2 Leonidas Poulopoulos
                    logger.error('Rule is applied on device but appears as offline')
253 e173e7c2 Leonidas Poulopoulos
                    self.status = "ACTIVE"
254 e173e7c2 Leonidas Poulopoulos
                    self.save()
255 e173e7c2 Leonidas Poulopoulos
                    found = True
256 33281310 Leonidas Poulopoulos
            if self.status == "ADMININACTIVE" or self.status == "INACTIVE" or self.status == "EXPIRED":
257 e173e7c2 Leonidas Poulopoulos
                found = True
258 357d48dc Leonidas Poulopoulos
        return found
259 357d48dc Leonidas Poulopoulos
260 357d48dc Leonidas Poulopoulos
    def get_then(self):
261 357d48dc Leonidas Poulopoulos
        ret = ''
262 b10e01d6 Leonidas Poulopoulos
        then_statements = self.then.all()
263 357d48dc Leonidas Poulopoulos
        for statement in then_statements:
264 357d48dc Leonidas Poulopoulos
            if statement.action_value:
265 357d48dc Leonidas Poulopoulos
                ret = "%s %s:<strong>%s</strong><br/>" %(ret, statement.action, statement.action_value)
266 357d48dc Leonidas Poulopoulos
            else: 
267 357d48dc Leonidas Poulopoulos
                ret = "%s %s<br>" %(ret, statement.action)
268 357d48dc Leonidas Poulopoulos
        return ret.rstrip(',')
269 357d48dc Leonidas Poulopoulos
    
270 357d48dc Leonidas Poulopoulos
    get_then.short_description = 'Then statement'
271 357d48dc Leonidas Poulopoulos
    get_then.allow_tags = True
272 b10e01d6 Leonidas Poulopoulos
#
273 357d48dc Leonidas Poulopoulos
    def get_match(self):
274 357d48dc Leonidas Poulopoulos
        ret = ''
275 b10e01d6 Leonidas Poulopoulos
        if self.destination:
276 97e42c7d Leonidas Poulopoulos
            ret = '%s Dst Addr:<strong>%s</strong><br/>' %(ret, self.destination)
277 b10e01d6 Leonidas Poulopoulos
        if self.fragmenttype:
278 3e99e2d1 Leonidas Poulopoulos
            ret = "%s Fragment Type:<strong>%s</strong><br/>" %(ret, self.fragmenttype)
279 b10e01d6 Leonidas Poulopoulos
        if self.icmpcode:
280 3e99e2d1 Leonidas Poulopoulos
            ret = "%s ICMP code:<strong>%s</strong><br/>" %(ret, self.icmpcode)
281 b10e01d6 Leonidas Poulopoulos
        if self.icmptype:
282 3e99e2d1 Leonidas Poulopoulos
            ret = "%s ICMP Type:<strong>%s</strong><br/>" %(ret, self.icmptype)
283 b10e01d6 Leonidas Poulopoulos
        if self.packetlength:
284 3e99e2d1 Leonidas Poulopoulos
            ret = "%s Packet Length:<strong>%s</strong><br/>" %(ret, self.packetlength)
285 b10e01d6 Leonidas Poulopoulos
        if self.protocol:
286 3e99e2d1 Leonidas Poulopoulos
            ret = "%s Protocol:<strong>%s</strong><br/>" %(ret, self.protocol)
287 b10e01d6 Leonidas Poulopoulos
        if self.source:
288 97e42c7d Leonidas Poulopoulos
            ret = "%s Src Addr:<strong>%s</strong><br/>" %(ret, self.source)
289 b10e01d6 Leonidas Poulopoulos
        if self.tcpflag:
290 3e99e2d1 Leonidas Poulopoulos
            ret = "%s TCP flag:<strong>%s</strong><br/>" %(ret, self.tcpflag)
291 b10e01d6 Leonidas Poulopoulos
        if self.port:
292 b10e01d6 Leonidas Poulopoulos
            for port in self.port.all():
293 3e99e2d1 Leonidas Poulopoulos
                    ret = ret + "Port:<strong>%s</strong><br/>" %(port)
294 b10e01d6 Leonidas Poulopoulos
        if self.destinationport:
295 b10e01d6 Leonidas Poulopoulos
            for port in self.destinationport.all():
296 97e42c7d Leonidas Poulopoulos
                    ret = ret + "Dst Port:<strong>%s</strong><br/>" %(port)
297 b10e01d6 Leonidas Poulopoulos
        if self.sourceport:
298 b10e01d6 Leonidas Poulopoulos
            for port in self.sourceport.all():
299 97e42c7d Leonidas Poulopoulos
                    ret = ret +"Src Port:<strong>%s</strong><br/>" %(port)
300 b10e01d6 Leonidas Poulopoulos
        if self.dscp:
301 b10e01d6 Leonidas Poulopoulos
            for dscp in self.dscp.all():
302 3e99e2d1 Leonidas Poulopoulos
                    ret = ret + "%s Port:<strong>%s</strong><br/>" %(ret, dscp)
303 357d48dc Leonidas Poulopoulos
        return ret.rstrip('<br/>')
304 357d48dc Leonidas Poulopoulos
        
305 357d48dc Leonidas Poulopoulos
    get_match.short_description = 'Match statement'
306 357d48dc Leonidas Poulopoulos
    get_match.allow_tags = True
307 d50fd7b6 Leonidas Poulopoulos
    
308 d50fd7b6 Leonidas Poulopoulos
    @property
309 d50fd7b6 Leonidas Poulopoulos
    def applier_peer(self):
310 d50fd7b6 Leonidas Poulopoulos
        try:
311 d50fd7b6 Leonidas Poulopoulos
            applier_peer = self.applier.get_profile().peer
312 d50fd7b6 Leonidas Poulopoulos
        except:
313 d50fd7b6 Leonidas Poulopoulos
            applier_peer = None
314 d50fd7b6 Leonidas Poulopoulos
        return applier_peer
315 fb67376a Leonidas Poulopoulos
    
316 fb67376a Leonidas Poulopoulos
    @property
317 fb67376a Leonidas Poulopoulos
    def days_to_expire(self):
318 fb67376a Leonidas Poulopoulos
        if self.status not in ['EXPIRED', 'ADMININACTIVE', 'ERROR']:
319 fb67376a Leonidas Poulopoulos
            expiration_days = (self.expires - datetime.date.today()).days
320 fb67376a Leonidas Poulopoulos
            if expiration_days < settings.EXPIRATION_NOTIFY_DAYS:
321 fb67376a Leonidas Poulopoulos
                return expiration_days
322 fb67376a Leonidas Poulopoulos
            else:
323 fb67376a Leonidas Poulopoulos
                return False
324 fb67376a Leonidas Poulopoulos
        else:
325 fb67376a Leonidas Poulopoulos
            return False
326 357d48dc Leonidas Poulopoulos
327 25d08a62 Leonidas Poulopoulos
def send_message(msg, user):
328 97e42c7d Leonidas Poulopoulos
#    username = user.username
329 97e42c7d Leonidas Poulopoulos
    peer = user
330 3e99e2d1 Leonidas Poulopoulos
    b = beanstalkc.Connection()
331 3e99e2d1 Leonidas Poulopoulos
    b.use(settings.POLLS_TUBE)
332 97e42c7d Leonidas Poulopoulos
    tube_message = json.dumps({'message': str(msg), 'username':peer})
333 25d08a62 Leonidas Poulopoulos
    b.put(tube_message)
334 3e99e2d1 Leonidas Poulopoulos
    b.close()