Statistics
| Branch: | Tag: | Revision:

root / flowspec / models.py @ b27537d5

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