Statistics
| Branch: | Tag: | Revision:

root / flowspec / tasks.py @ 15d4014d

History | View | Annotate | Download (7.1 kB)

1
from utils import proxy as PR
2
from celery.task import task
3
from celery.task.sets import subtask
4
import logging
5
import json
6
from celery.task.http import *
7
import beanstalkc
8
from django.conf import settings
9
import datetime
10
from flowspy.flowspec.models import *
11
from django.core.mail import send_mail
12
from flowspy.flowspec.models import *
13
from django.template.loader import render_to_string
14
from django.contrib.sites.models import Site
15
from django.core.urlresolvers import reverse
16
import os
17

    
18

    
19

    
20
LOG_FILENAME = os.path.join(settings.LOG_FILE_LOCATION, 'celery_jobs.log')
21

    
22
#FORMAT = '%(asctime)s %(levelname)s: %(message)s'
23
#logging.basicConfig(format=FORMAT)
24
formatter = logging.Formatter('%(asctime)s %(levelname)s: %(message)s')
25

    
26
logger = logging.getLogger(__name__)
27
logger.setLevel(logging.DEBUG)
28
handler = logging.FileHandler(LOG_FILENAME)
29
handler.setFormatter(formatter)
30
logger.addHandler(handler)
31

    
32

    
33
@task(ignore_result=True)
34
def add(route, callback=None):
35
    applier = PR.Applier(route_object=route)
36
    commit, response = applier.apply()
37
    if commit:
38
        status = "ACTIVE"
39
    else:
40
        status = "ERROR"
41
    route.status = status
42
    route.response = response
43
    route.save()
44
    announce("[%s] Rule add: %s - Result: %s" %(route.applier, route.name, response), route.applier)
45

    
46
@task(ignore_result=True)
47
def edit(route, callback=None):
48
    applier = PR.Applier(route_object=route)
49
    commit, response = applier.apply(operation="replace")
50
    if commit:
51
        status = "ACTIVE"
52
    else:
53
        status = "ERROR"
54
    route.status = status
55
    route.response = response
56
    route.save()
57
    announce("[%s] Rule edit: %s - Result: %s"%(route.applier, route.name, response), route.applier)
58

    
59

    
60

    
61
@task(ignore_result=True)
62
def delete(route, **kwargs):
63
    applier = PR.Applier(route_object=route)
64
    commit, response = applier.apply(operation="delete")
65
    reason_text = ''
66
    if commit:
67
        status = "INACTIVE"
68
        if "reason" in kwargs and kwargs['reason']=='EXPIRED':
69
            status = 'EXPIRED'
70
            reason_text = " Reason: %s " %status
71
    else:
72
        status = "ERROR"
73
    route.status = status
74
    route.response = response
75
    route.save()
76
    announce("[%s] Suspending rule : %s%s- Result %s" %(route.applier, route.name, reason_text, response), route.applier)
77

    
78
# May not work in the first place... proxy is not aware of Route models
79
@task
80
def batch_delete(routes, **kwargs):
81
    if routes:
82
        for route in routes:
83
            route.status='PENDING';route.save()
84
        applier = PR.Applier(route_objects=routes)
85
        conf = applier.delete_routes()
86
        commit, response = applier.apply(configuration = conf)
87
        reason_text = ''
88
        if commit:
89
            status = "INACTIVE"
90
            if "reason" in kwargs and kwargs['reason']=='EXPIRED':
91
                status = 'EXPIRED'
92
                reason_text = " Reason: %s " %status
93
            elif "reason" in kwargs and kwargs['reason']!='EXPIRED':
94
                status = kwargs['reason']
95
                reason_text = " Reason: %s " %status
96
        else:
97
            status = "ERROR"
98
        for route in routes:
99
            route.status = status
100
            route.response = response
101
            route.expires = datetime.date.today()
102
            route.save()
103
            announce("[%s] Rule removal: %s%s- Result %s" %(route.applier, route.name, reason_text, response), route.applier)
104
    else:
105
        return False
106

    
107
#@task(ignore_result=True)
108
def announce(messg, user):
109
    messg = str(messg)
110
#    username = user.username
111
    username = user.get_profile().peer.domain_name
112
    b = beanstalkc.Connection()
113
    b.use(settings.POLLS_TUBE)
114
    tube_message = json.dumps({'message': messg, 'username':username})
115
    b.put(tube_message)
116
    b.close()
117

    
118
@task
119
def check_sync(route_name=None, selected_routes = []):
120
    from flowspy.flowspec.models import Route, MatchPort, MatchDscp, ThenAction
121
    if not selected_routes:
122
        routes = Route.objects.all()
123
    else:
124
        routes = selected_routes
125
    if route_name:
126
        routes = routes.filter(name=route_name)
127
    for route in routes:
128
        if route.has_expired() and (route.status != 'EXPIRED' and route.status != 'ADMININACTIVE' and route.status != 'INACTIVE'):
129
            logger.info('Expiring route %s' %route.name)
130
            subtask(delete).delay(route, reason="EXPIRED")
131
#        elif route.has_expired() and (route.status == 'ADMININACTIVE' or route.status == 'INACTIVE'):
132
#            route.status = 'EXPIRED'
133
#            route.response = 'Rule Expired'
134
#            logger.info('Expiring route %s' %route.name)
135
#            route.save()
136
        else:
137
            if route.status != 'EXPIRED':
138
                route.check_sync()
139

    
140
@task(ignore_result=True)
141
def notify_expired():
142
    logger.info('Initializing expiration notification')
143
    routes = Route.objects.all()
144
    for route in routes:
145
        if route.status not in ['EXPIRED', 'ADMININACTIVE', 'INACTIVE', 'ERROR']:
146
            expiration_days = (route.expires - datetime.date.today()).days
147
            if expiration_days < settings.EXPIRATION_NOTIFY_DAYS:
148
                try:
149
                    fqdn = Site.objects.get_current().domain
150
                    admin_url = "https://%s%s" % \
151
                    (fqdn,
152
                     "/fod/edit/%s"%route.name)
153
                    mail_body = render_to_string("rule_expiration.txt",
154
                                             {"route": route, 'expiration_days':expiration_days, 'url':admin_url})
155
                    days_num = ' days'
156
                    expiration_days_text = "%s %s" %('in',expiration_days)
157
                    if expiration_days == 0:
158
                        days_num = ' today'
159
                        expiration_days_text = ''
160
                    if expiration_days == 1:
161
                        days_num = ' day'
162
                    logger.info('Route %s expires %s%s. Notifying %s (%s)' %(route.name, expiration_days_text, days_num, route.applier.username, route.applier.email))
163
                    send_mail(settings.EMAIL_SUBJECT_PREFIX + "Rule %s expires %s%s" %
164
                              (route.name,expiration_days_text, days_num),
165
                              mail_body, settings.SERVER_EMAIL,
166
                              [route.applier.email])
167
                except Exception as e:
168
                    logger.info("Exception: %s"%e)
169
                    pass
170
    logger.info('Expiration notification process finished')
171

    
172
#def delete(route):
173
#    
174
#    applier = PR.Applier(route_object=route)
175
#    commit, response = applier.apply(configuration=applier.delete_routes())
176
#    if commit:
177
#            rows = queryset.update(is_online=False, is_active=False)
178
#            queryset.update(response="Successfully removed route from network")
179
#            self.message_user(request, "Successfully removed %s routes from network" % rows)
180
#        else:
181
#            self.message_user(request, "Could not remove routes from network")
182
#    if commit:
183
#        is_online = False
184
#        is_active = False
185
#        response = "Successfully removed route from network"
186
#    else:
187
#        is_online = False
188
#        is_active = True
189
#    route.is_online = is_online
190
#    route.is_active = is_active
191
#    route.response = response
192
#    route.save()