tasks.py 7.15 KB
Newer Older
1
2
from utils import proxy as PR
from celery.task import task
3
4
from celery.task.sets import subtask
import logging
5
import json
6
from celery.task.http import *
7
import beanstalkc
8
from django.conf import settings
9
import datetime
10
11
12
from django.core.mail import send_mail
from django.template.loader import render_to_string
from django.core.urlresolvers import reverse
13
14
15
import os


16
17

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

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

23
24
logger = logging.getLogger(__name__)
logger.setLevel(logging.DEBUG)
25
26
27
28
handler = logging.FileHandler(LOG_FILENAME)
handler.setFormatter(formatter)
logger.addHandler(handler)

29

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

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


57

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

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

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

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

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

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